This commit is contained in:
jxxghp
2024-05-16 20:31:30 +08:00
parent 5580921b7d
commit fc877ed836
14 changed files with 53 additions and 88 deletions
+12 -1
View File
@@ -447,6 +447,17 @@ export interface Plugin {
add_time?: number add_time?: number
} }
// 渲染结构
export interface RenderProps {
component: string
text?: string
html?: string
content?: any
slots?: any
props?: any
events?: any
}
// 仪表板组件 // 仪表板组件
export interface DashboardItem { export interface DashboardItem {
// ID // ID
@@ -458,7 +469,7 @@ export interface DashboardItem {
// col列数 // col列数
cols: { [key: string]: number } cols: { [key: string]: number }
// 页面元素 // 页面元素
elements: { [key: string]: any }[] elements: RenderProps[]
} }
// 种子信息 // 种子信息
+3
View File
@@ -477,7 +477,10 @@ function getYear(airDate: string) {
<VBottomSheet v-if="subscribeSeasonDialog" v-model="subscribeSeasonDialog" inset scrollable> <VBottomSheet v-if="subscribeSeasonDialog" v-model="subscribeSeasonDialog" inset scrollable>
<VCard class="rounded-t"> <VCard class="rounded-t">
<DialogCloseBtn @click="subscribeSeasonDialog = false" /> <DialogCloseBtn @click="subscribeSeasonDialog = false" />
<VCardItem>
<VCardTitle class="pe-10"> 订阅 - {{ props.media?.title }} </VCardTitle> <VCardTitle class="pe-10"> 订阅 - {{ props.media?.title }} </VCardTitle>
</VCardItem>
<VDivider />
<VCardText> <VCardText>
<VList v-model:selected="seasonsSelected" lines="three" select-strategy="classic"> <VList v-model:selected="seasonsSelected" lines="three" select-strategy="classic">
<VListItem v-for="(item, i) in seasonInfos" :key="i" :value="item"> <VListItem v-for="(item, i) in seasonInfos" :key="i" :value="item">
+1
View File
@@ -215,6 +215,7 @@ const dropdownItems = ref([
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable> <VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
<VCard :title="`${props.plugin?.plugin_name} 更新说明`"> <VCard :title="`${props.plugin?.plugin_name} 更新说明`">
<DialogCloseBtn @click="releaseDialog = false" /> <DialogCloseBtn @click="releaseDialog = false" />
<VDivider />
<VersionHistory :history="props.plugin?.history" /> <VersionHistory :history="props.plugin?.history" />
</VCard> </VCard>
</VDialog> </VDialog>
+5 -5
View File
@@ -435,6 +435,7 @@ watch(
<VDialog v-model="pluginConfigDialog" scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value"> <VDialog v-model="pluginConfigDialog" scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value">
<VCard :title="`${props.plugin?.plugin_name} - 配置`" class="rounded-t"> <VCard :title="`${props.plugin?.plugin_name} - 配置`" class="rounded-t">
<DialogCloseBtn v-model="pluginConfigDialog" /> <DialogCloseBtn v-model="pluginConfigDialog" />
<VDivider />
<VCardText> <VCardText>
<FormRender v-for="(item, index) in pluginFormItems" :key="index" :config="item" :form="pluginConfigForm" /> <FormRender v-for="(item, index) in pluginFormItems" :key="index" :config="item" :form="pluginConfigForm" />
</VCardText> </VCardText>
@@ -452,13 +453,10 @@ watch(
<VDialog v-model="pluginInfoDialog" scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value"> <VDialog v-model="pluginInfoDialog" scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">
<VCard :title="`${props.plugin?.plugin_name}`" class="rounded-t"> <VCard :title="`${props.plugin?.plugin_name}`" class="rounded-t">
<DialogCloseBtn v-model="pluginInfoDialog" /> <DialogCloseBtn v-model="pluginInfoDialog" />
<VCardText> <VCardText class="min-h-40">
<PageRender @action="loadPluginPage" v-for="(item, index) in pluginPageItems" :key="index" :config="item" /> <PageRender @action="loadPluginPage" v-for="(item, index) in pluginPageItems" :key="index" :config="item" />
</VCardText> </VCardText>
<VCardActions class="pt-3"> <VFab icon="mdi-cog" location="bottom end" size="x-large" fixed app appear @click="showPluginConfig" />
<VSpacer />
<VBtn @click="showPluginConfig" variant="elevated" prepend-icon="mdi-cog" class="px-5"> 配置 </VBtn>
</VCardActions>
</VCard> </VCard>
</VDialog> </VDialog>
@@ -469,7 +467,9 @@ watch(
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable> <VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
<VCard :title="`${props.plugin?.plugin_name} 更新说明`"> <VCard :title="`${props.plugin?.plugin_name} 更新说明`">
<DialogCloseBtn @click="releaseDialog = false" /> <DialogCloseBtn @click="releaseDialog = false" />
<VDivider />
<VersionHistory :history="props.plugin?.history" /> <VersionHistory :history="props.plugin?.history" />
<VDivider />
<VCardText> <VCardText>
<VBtn @click="updatePlugin" block> <VBtn @click="updatePlugin" block>
<template #prepend> <template #prepend>
+1
View File
@@ -308,6 +308,7 @@ onMounted(() => {
<!-- Dialog Content --> <!-- Dialog Content -->
<VCard :title="`浏览站点 - ${cardProps.site?.name}`"> <VCard :title="`浏览站点 - ${cardProps.site?.name}`">
<DialogCloseBtn @click="resourceDialog = false" /> <DialogCloseBtn @click="resourceDialog = false" />
<VDivider />
<VCardText class="pt-2"> <VCardText class="pt-2">
<SiteTorrentTable :site="cardProps.site?.id" /> <SiteTorrentTable :site="cardProps.site?.id" />
</VCardText> </VCardText>
+2 -1
View File
@@ -169,7 +169,8 @@ onMounted(() => {
class="rounded-t" class="rounded-t"
> >
<DialogCloseBtn @click="emit('close')" /> <DialogCloseBtn @click="emit('close')" />
<VCardText class="pt-2"> <VDivider />
<VCardText>
<VForm @submit.prevent="() => {}"> <VForm @submit.prevent="() => {}">
<VRow> <VRow>
<VCol cols="12" md="8"> <VCol cols="12" md="8">
+2 -1
View File
@@ -133,7 +133,8 @@ async function updateSiteInfo() {
class="rounded-t" class="rounded-t"
> >
<DialogCloseBtn @click="emit('close')" /> <DialogCloseBtn @click="emit('close')" />
<VCardText class="pt-2"> <VDivider />
<VCardText>
<VForm @submit.prevent="() => {}"> <VForm @submit.prevent="() => {}">
<VRow> <VRow>
<VCol cols="12" md="6"> <VCol cols="12" md="6">
@@ -269,7 +269,8 @@ onMounted(() => {
}`" }`"
class="rounded-t" class="rounded-t"
> >
<VCardText class="pt-2"> <VDivider />
<VCardText>
<DialogCloseBtn @click="emit('close')" /> <DialogCloseBtn @click="emit('close')" />
<VForm @submit.prevent="() => {}"> <VForm @submit.prevent="() => {}">
<VRow> <VRow>
@@ -369,7 +370,6 @@ onMounted(() => {
</VRow> </VRow>
</VForm> </VForm>
</VCardText> </VCardText>
<VCardActions class="pt-3"> <VCardActions class="pt-3">
<VBtn v-if="!props.default" color="error" @click="removeSubscribe" variant="outlined" class="me-3"> <VBtn v-if="!props.default" color="error" @click="removeSubscribe" variant="outlined" class="me-3">
取消订阅 取消订阅
@@ -134,9 +134,10 @@ const dropdownItems = ref([
<template> <template>
<VDialog scrollable max-width="50rem" :fullscreen="!display.mdAndUp.value"> <VDialog scrollable max-width="50rem" :fullscreen="!display.mdAndUp.value">
<VCard class="mx-auto" width="100%"> <VCard class="mx-auto" width="100%">
<VCardItem class="pb-0"> <VCardItem>
<VCardTitle>{{ props.type + '订阅历史' }}</VCardTitle> <VCardTitle>{{ props.type + '订阅历史' }}</VCardTitle>
</VCardItem> </VCardItem>
<VDivider />
<DialogCloseBtn <DialogCloseBtn
@click=" @click="
() => { () => {
+1
View File
@@ -110,6 +110,7 @@ onMounted(() => {
} }
" "
/> />
<VDivider />
<VList v-if="items.length > 0" lines="three"> <VList v-if="items.length > 0" lines="three">
<template v-for="(item, i) in items" :key="i"> <template v-for="(item, i) in items" :key="i">
<VListItem @click="selectMedia(item)"> <VListItem @click="selectMedia(item)">
+1 -10
View File
@@ -1,16 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { RenderProps } from '@/api/types'
import { type PropType } from 'vue' import { type PropType } from 'vue'
// 组件接口
interface RenderProps {
component: string
text: string
html: string
content?: any
slots?: any
props?: any
}
// 输入参数 // 输入参数
const elementProps = defineProps({ const elementProps = defineProps({
config: Object as PropType<RenderProps>, config: Object as PropType<RenderProps>,
+11 -43
View File
@@ -1,15 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { RenderProps } from '@/api/types'
import { type PropType, ref } from 'vue' import { type PropType, ref } from 'vue'
// 组件接口
interface RenderProps {
component: string
text: string
html: string
content?: any
props?: any
}
// 输入参数 // 输入参数
const elementProps = defineProps({ const elementProps = defineProps({
config: Object as PropType<RenderProps>, config: Object as PropType<RenderProps>,
@@ -17,13 +9,15 @@ const elementProps = defineProps({
}) })
// 配置元素 // 配置元素
const formItem = ref<RenderProps>(elementProps.config ?? { const formItem = ref<RenderProps>(
elementProps.config ?? {
component: 'div', component: 'div',
text: '', text: '',
html: '', html: '',
props: {}, props: {},
content: [], content: [],
}) },
)
// 配置数据 // 配置数据
const formData = ref<any>(elementProps.form || {}) const formData = ref<any>(elementProps.form || {})
@@ -37,53 +31,27 @@ const formData = ref<any>(elementProps.form || {})
v-model:value="formData[formItem.props?.modelvalue]" v-model:value="formData[formItem.props?.modelvalue]"
> >
{{ formItem.text }} {{ formItem.text }}
<template <template v-for="(innerItem, innerIndex) in formItem.content || []" :key="innerIndex">
v-for="(innerItem, innerIndex) in (formItem.content || [])"
:key="innerIndex"
>
<FormRender <FormRender
v-if="!!innerItem.props?.modelvalue" v-if="!!innerItem.props?.modelvalue"
v-model:value="formData[innerItem.props?.modelvalue]" v-model:value="formData[innerItem.props?.modelvalue]"
:config="innerItem" :config="innerItem"
:form="formData" :form="formData"
/> />
<FormRender <FormRender v-else v-model="formData[innerItem.props?.model]" :config="innerItem" :form="formData" />
v-else
v-model="formData[innerItem.props?.model]"
:config="innerItem"
:form="formData"
/>
</template> </template>
</Component> </Component>
<Component <Component :is="formItem.component" v-else-if="formItem.html" v-bind="formItem.props" v-html="formItem.html" />
:is="formItem.component" <Component :is="formItem.component" v-else v-bind="formItem.props" v-model="formData[formItem.props?.model]">
v-else-if="formItem.html"
v-bind="formItem.props"
v-html="formItem.html"
/>
<Component
:is="formItem.component"
v-else
v-bind="formItem.props"
v-model="formData[formItem.props?.model]"
>
{{ formItem.text }} {{ formItem.text }}
<template <template v-for="(innerItem, innerIndex) in formItem.content || []" :key="innerIndex">
v-for="(innerItem, innerIndex) in (formItem.content || [])"
:key="innerIndex"
>
<FormRender <FormRender
v-if="!!innerItem.props?.modelvalue" v-if="!!innerItem.props?.modelvalue"
v-model:value="formData[innerItem.props?.modelvalue]" v-model:value="formData[innerItem.props?.modelvalue]"
:config="innerItem" :config="innerItem"
:form="formData" :form="formData"
/> />
<FormRender <FormRender v-else v-model="formData[innerItem.props?.model]" :config="innerItem" :form="formData" />
v-else
v-model="formData[innerItem.props?.model]"
:config="innerItem"
:form="formData"
/>
</template> </template>
</Component> </Component>
</template> </template>
+1 -11
View File
@@ -3,21 +3,11 @@ import { isNullOrEmptyObject } from '@/@core/utils'
import api from '@/api' import api from '@/api'
import { type PropType } from 'vue' import { type PropType } from 'vue'
import ProgressDialog from '../dialog/ProgressDialog.vue' import ProgressDialog from '../dialog/ProgressDialog.vue'
import { RenderProps } from '@/api/types'
// 定议外部事件 // 定议外部事件
const emit = defineEmits(['action']) const emit = defineEmits(['action'])
// 组件接口
interface RenderProps {
component: string
text: string
html: string
content?: any
slots?: any
props?: any
events?: any
}
// 输入参数 // 输入参数
const elementProps = defineProps({ const elementProps = defineProps({
config: Object as PropType<RenderProps>, config: Object as PropType<RenderProps>,
+3 -7
View File
@@ -2,14 +2,10 @@
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
import api from '@/api' import api from '@/api'
import { isNullOrEmptyObject } from '@/@core/utils' import { isNullOrEmptyObject } from '@/@core/utils'
import { useDisplay } from 'vuetify'
import { DashboardItem } from '@/api/types' import { DashboardItem } from '@/api/types'
import store from '@/store' import store from '@/store'
import DashboardElement from '@/components/misc/DashboardElement.vue' import DashboardElement from '@/components/misc/DashboardElement.vue'
// 显示器宽度
const display = useDisplay()
// 从Vuex Store中获取superuser信息 // 从Vuex Store中获取superuser信息
const superUser = store.state.auth.superUser const superUser = store.state.auth.superUser
@@ -107,6 +103,9 @@ const dashboardConfigs = ref<DashboardItem[]>([
// 有仪表板的插件 // 有仪表板的插件
const dashboardPlugins = ref<any[]>([]) const dashboardPlugins = ref<any[]>([])
// 插件仪表板的刷新状态
const pluginDashboardRefreshStatus = ref<{ [key: string]: boolean }>({})
// 弹窗 // 弹窗
const dialog = ref(false) const dialog = ref(false)
@@ -196,9 +195,6 @@ async function getDashboardPlugins() {
} }
} }
// 插件仪表板的刷新状态
const pluginDashboardRefreshStatus = ref<{ [key: string]: boolean }>({})
// 获取一个插件的仪表板配置项 // 获取一个插件的仪表板配置项
async function getPluginDashboard(id: string) { async function getPluginDashboard(id: string) {
try { try {