调整卡片组件的样式,优化悬停效果,提升用户体验

This commit is contained in:
jxxghp
2025-04-01 18:52:07 +08:00
parent 6a6a3bd463
commit 3c261a2c29
14 changed files with 331 additions and 295 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ const getImgUrl = computed(() => {
:width="props.width" :width="props.width"
class="ring-gray-500" class="ring-gray-500"
:class="{ :class="{
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering, 'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
'ring-1': imageLoaded, 'ring-1': imageLoaded,
}" }"
@click="goPlay" @click="goPlay"
+34 -27
View File
@@ -143,35 +143,42 @@ onUnmounted(() => {
</script> </script>
<template> <template>
<div> <div>
<VCard variant="tonal" @click="openDownloaderInfoDialog"> <VHover v-slot="hover">
<DialogCloseBtn @click="onClose" /> <VCard
<span class="absolute top-3 right-12"> v-bind="hover.props"
<IconBtn> variant="tonal"
<VIcon class="cursor-move" icon="mdi-drag" /> @click="openDownloaderInfoDialog"
</IconBtn> :class="{ 'transition transform-cpu duration-300 -translate-y-1': hover.isHovering }"
</span> >
<VCardText class="flex justify-space-between align-center gap-4"> <DialogCloseBtn @click="onClose" />
<div class="align-self-start flex-1"> <span class="absolute top-3 right-12">
<div class="flex items-center"> <IconBtn>
<VBadge <VIcon class="cursor-move" icon="mdi-drag" />
v-if="props.downloader.default && props.downloader.enabled" </IconBtn>
dot </span>
inline <VCardText class="flex justify-space-between align-center gap-4">
color="success" <div class="align-self-start flex-1">
class="me-1" <div class="flex items-center">
/> <VBadge
<span class="text-h6">{{ downloader.name }}</span> v-if="props.downloader.default && props.downloader.enabled"
dot
inline
color="success"
class="me-1"
/>
<span class="text-h6">{{ downloader.name }}</span>
</div>
<div class="mt-1 flex flex-wrap text-sm" v-if="props.downloader.enabled">
<span class="me-2">{{ `${formatFileSize(upload_rate, 1)}/s ` }}</span>
<span>{{ `${formatFileSize(download_rate, 1)}/s` }}</span>
</div>
</div> </div>
<div class="mt-1 flex flex-wrap text-sm" v-if="props.downloader.enabled"> <div class="h-20">
<span class="me-2">{{ `${formatFileSize(upload_rate, 1)}/s ` }}</span> <VImg :src="getIcon" cover class="mt-7 me-3" max-width="3rem" min-width="3rem" />
<span>{{ `${formatFileSize(download_rate, 1)}/s` }}</span>
</div> </div>
</div> </VCardText>
<div class="h-20"> </VCard>
<VImg :src="getIcon" cover class="mt-7 me-3" max-width="3rem" min-width="3rem" /> </VHover>
</div>
</VCardText>
</VCard>
<VDialog v-if="downloaderInfoDialog" v-model="downloaderInfoDialog" scrollable max-width="40rem" persistent> <VDialog v-if="downloaderInfoDialog" v-model="downloaderInfoDialog" scrollable max-width="40rem" persistent>
<VCard :title="`${props.downloader.name} - 配置`" class="rounded-t"> <VCard :title="`${props.downloader.name} - 配置`" class="rounded-t">
<DialogCloseBtn v-model="downloaderInfoDialog" /> <DialogCloseBtn v-model="downloaderInfoDialog" />
+1 -1
View File
@@ -158,7 +158,7 @@ onMounted(async () => {
:height="props.height" :height="props.height"
:width="props.width" :width="props.width"
:class="{ :class="{
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering, 'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
}" }"
@click="goPlay" @click="goPlay"
> >
+1 -1
View File
@@ -532,7 +532,7 @@ function onRemoveSubscribe() {
:width="props.width" :width="props.width"
class="outline-none shadow ring-gray-500 rounded-lg" class="outline-none shadow ring-gray-500 rounded-lg"
:class="{ :class="{
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering, 'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
'ring-1': isImageLoaded, 'ring-1': isImageLoaded,
}" }"
@click.stop="goMediaDetail(hover.isHovering ?? false)" @click.stop="goMediaDetail(hover.isHovering ?? false)"
+1 -1
View File
@@ -79,7 +79,7 @@ function goPersonDetail() {
:width="personProps.width" :width="personProps.width"
class="rounded-lg" class="rounded-lg"
:class="{ :class="{
'transition transform-cpu duration-300 scale-105': hover.isHovering, 'transition transform-cpu duration-300 -translate-y-1': hover.isHovering,
}" }"
@click.stop="goPersonDetail" @click.stop="goPersonDetail"
> >
+80 -65
View File
@@ -147,72 +147,87 @@ const dropdownItems = ref([
<template> <template>
<div> <div>
<VCard :width="props.width" :height="props.height" @click="detailDialog = true" class="flex flex-col h-full"> <VHover>
<div <template #default="hover">
class="relative flex flex-row items-start pa-3 justify-between grow" <VCard
:style="{ background: `${backgroundColor}` }" v-bind="hover.props"
> :width="props.width"
<div :height="props.height"
class="absolute inset-0 bg-cover bg-center" @click="detailDialog = true"
:style="{ background: `${backgroundColor}`, filter: 'brightness(0.5)' }" class="flex flex-col h-full"
></div> :class="{
<div class="relative flex-1 min-w-0"> 'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
<VCardTitle class="text-white text-lg px-2 text-shadow whitespace-nowrap overflow-hidden text-ellipsis ..."> }"
{{ props.plugin?.plugin_name }} >
<span class="text-sm text-gray-200">v{{ props.plugin?.plugin_version }}</span> <div
</VCardTitle> class="relative flex flex-row items-start pa-3 justify-between grow"
<VCardText class="text-white text-sm px-2 py-0 text-shadow overflow-hidden line-clamp-3 ..."> :style="{ background: `${backgroundColor}` }"
{{ props.plugin?.plugin_desc }} >
<div
class="absolute inset-0 bg-cover bg-center"
:style="{ background: `${backgroundColor}`, filter: 'brightness(0.5)' }"
></div>
<div class="relative flex-1 min-w-0">
<VCardTitle
class="text-white text-lg px-2 text-shadow whitespace-nowrap overflow-hidden text-ellipsis ..."
>
{{ props.plugin?.plugin_name }}
<span class="text-sm text-gray-200">v{{ props.plugin?.plugin_version }}</span>
</VCardTitle>
<VCardText class="text-white text-sm px-2 py-0 text-shadow overflow-hidden line-clamp-3 ...">
{{ props.plugin?.plugin_desc }}
</VCardText>
</div>
<div class="relative flex-shrink-0 self-center">
<VAvatar size="64">
<VImg
ref="imageRef"
:src="iconPath"
aspect-ratio="4/3"
cover
:class="{ shadow: isImageLoaded }"
@load="imageLoaded"
@error="imageLoadError = true"
/>
</VAvatar>
</div>
</div>
<VCardText class="flex flex-none align-self-baseline py-3 w-full align-end">
<span>
<VIcon icon="mdi-github" class="me-1" />
<a :href="props.plugin?.author_url" target="_blank" @click.stop>
{{ props.plugin?.plugin_author }}
</a>
</span>
<span v-if="props.count" class="ms-3">
<VIcon icon="mdi-download" />
<span class="text-sm ms-1 mt-1">{{ props.count?.toLocaleString() }}</span>
</span>
<div class="me-n3 absolute bottom-1 right-3">
<IconBtn>
<VIcon icon="mdi-dots-vertical" />
<VMenu activator="parent" close-on-content-click>
<VList>
<VListItem
v-for="(item, i) in dropdownItems"
v-show="item.show"
:key="i"
variant="plain"
@click="item.props.click"
>
<template #prepend>
<VIcon :icon="item.props.prependIcon" />
</template>
<VListItemTitle v-text="item.title" />
</VListItem>
</VList>
</VMenu>
</IconBtn>
</div>
</VCardText> </VCardText>
</div> </VCard>
<div class="relative flex-shrink-0 self-center"> </template>
<VAvatar size="64"> </VHover>
<VImg
ref="imageRef"
:src="iconPath"
aspect-ratio="4/3"
cover
:class="{ shadow: isImageLoaded }"
@load="imageLoaded"
@error="imageLoadError = true"
/>
</VAvatar>
</div>
</div>
<VCardText class="flex flex-none align-self-baseline py-3 w-full align-end">
<span>
<VIcon icon="mdi-github" class="me-1" />
<a :href="props.plugin?.author_url" target="_blank" @click.stop>
{{ props.plugin?.plugin_author }}
</a>
</span>
<span v-if="props.count" class="ms-3">
<VIcon icon="mdi-download" />
<span class="text-sm ms-1 mt-1">{{ props.count?.toLocaleString() }}</span>
</span>
<div class="me-n3 absolute bottom-1 right-3">
<IconBtn>
<VIcon icon="mdi-dots-vertical" />
<VMenu activator="parent" close-on-content-click>
<VList>
<VListItem
v-for="(item, i) in dropdownItems"
v-show="item.show"
:key="i"
variant="plain"
@click="item.props.click"
>
<template #prepend>
<VIcon :icon="item.props.prependIcon" />
</template>
<VListItemTitle v-text="item.title" />
</VListItem>
</VList>
</VMenu>
</IconBtn>
</div>
</VCardText>
</VCard>
<!-- 安装插件进度框 --> <!-- 安装插件进度框 -->
<ProgressDialog v-if="progressDialog" v-model="progressDialog" :text="progressText" /> <ProgressDialog v-if="progressDialog" v-model="progressDialog" :text="progressText" />
<!-- 更新日志 --> <!-- 更新日志 -->
+3
View File
@@ -335,6 +335,9 @@ watch(
:height="props.height" :height="props.height"
@click="openPluginDetail" @click="openPluginDetail"
class="flex flex-col h-full" class="flex flex-col h-full"
:class="{
'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
}"
> >
<div <div
class="relative flex flex-row items-start pa-3 justify-between grow" class="relative flex flex-row items-start pa-3 justify-between grow"
+1 -1
View File
@@ -45,7 +45,7 @@ function goPlay(isHovering: boolean | null = false) {
:width="props.width" :width="props.width"
class="outline-none shadow ring-gray-500 rounded-lg" class="outline-none shadow ring-gray-500 rounded-lg"
:class="{ :class="{
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering, 'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
'ring-1': isImageLoaded, 'ring-1': isImageLoaded,
}" }"
> >
+2 -2
View File
@@ -390,14 +390,14 @@ onMounted(() => {
background: rgba(var(--v-theme-surface), 0.95); background: rgba(var(--v-theme-surface), 0.95);
border-radius: 10px; border-radius: 10px;
border: 1px solid rgba(var(--v-theme-on-surface), 0.09); border: 1px solid rgba(var(--v-theme-on-surface), 0.09);
transition: all 0.25s ease; transition: all 0.3s ease;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.site-card:hover { .site-card:hover {
transform: translateY(-2px); transform: translateY(-4px);
border-color: rgba(var(--v-theme-primary), 0.2); border-color: rgba(var(--v-theme-primary), 0.2);
box-shadow: 0 3px 12px -6px rgba(0, 0, 0, 0.1); box-shadow: 0 3px 12px -6px rgba(0, 0, 0, 0.1);
} }
+1 -1
View File
@@ -298,7 +298,7 @@ function onSubscribeEditRemove() {
class="flex flex-col rounded-lg h-full" class="flex flex-col rounded-lg h-full"
:class="{ :class="{
'outline-dashed outline-1': props.media?.best_version && imageLoaded, 'outline-dashed outline-1': props.media?.best_version && imageLoaded,
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering, 'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
'opacity-70': subscribeState === 'S', 'opacity-70': subscribeState === 'S',
}" }"
min-height="170" min-height="170"
+1 -1
View File
@@ -102,7 +102,7 @@ function doDelete() {
:key="props.media?.id" :key="props.media?.id"
class="flex flex-col rounded-lg h-full" class="flex flex-col rounded-lg h-full"
:class="{ :class="{
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering, 'transition transform-cpu duration-300 -translate-y-1 shadow-lg': hover.isHovering,
}" }"
min-height="170" min-height="170"
@click="showForkSubscribe" @click="showForkSubscribe"
+75 -73
View File
@@ -45,6 +45,12 @@ const movieSubscriptions = ref(0)
// 用户电视剧订阅数量 // 用户电视剧订阅数量
const tvShowSubscriptions = ref(0) const tvShowSubscriptions = ref(0)
// 新增:用户状态背景颜色计算
const statusClass = computed(() => ({
'bg-error-lighten-4': !props.user.is_active, // 假设用户状态使用 is_active 字段
'border-error': !props.user.is_active, // 非活跃用户添加红色边框
}))
// 按用户查询订阅数量 // 按用户查询订阅数量
async function fetchSubscriptions() { async function fetchSubscriptions() {
try { try {
@@ -98,88 +104,84 @@ onMounted(() => {
}) })
</script> </script>
<template> <template>
<VCard> <VHover v-slot="hover">
<VCardText class="text-center pt-10 pb-3"> <VCard
<VAvatar variant="flat" size="100" rounded> v-bind="hover.props"
<VImg :src="user.avatar || avatar1" alt="avatar" /> class="w-full h-full"
</VAvatar> :class="{ 'transition transform-cpu duration-300 -translate-y-1': hover.isHovering, ...statusClass }"
<h5 class="text-h5 mt-3">{{ user.name }}</h5> @click.stop="editUser"
<VChip size="small" class="mt-3" :class="{ 'text-error': user.is_superuser }"> >
<!-- 用户头像 -->
<VImg height="12rem" :src="user.avatar ?? avatar1" cover>
<div v-if="!user.is_active" class="img-overlay" />
</VImg>
<div class="flex flex-col">
<!-- 用户基本信息 -->
<VCardTitle class="pt-2">{{ user.name }}</VCardTitle>
<VCardSubtitle v-if="user.email" class="text-wrap">
<VIcon size="16">mdi-email</VIcon>
{{ user.email }}
</VCardSubtitle>
<!-- 订阅信息 -->
<VCardActions>
<div class="mt-3 flex gap-3" dense>
<VChip v-if="user.is_otp" size="small" color="error">
<VIcon>mdi-lock</VIcon>
</VChip>
<VChip size="small" color="info">
<VIcon left class="me-2">mdi-movie</VIcon>
{{ movieSubscriptions }}
</VChip>
<VChip size="small" color="warning">
<VIcon left class="me-2">mdi-television</VIcon>
{{ tvShowSubscriptions }}
</VChip>
</div>
</VCardActions>
</div>
<!-- 管理员标签 -->
<VChip
variant="elevated"
size="small"
class="absolute right-2 top-2"
:color="user.is_superuser ? 'primary' : 'secondary'"
>
{{ user.is_superuser ? '管理员' : '普通用户' }} {{ user.is_superuser ? '管理员' : '普通用户' }}
</VChip> </VChip>
</VCardText> <!-- 删除按钮 -->
<VCardText class="flex justify-center gap-6 pb-5"> <div class="absolute bottom-2 w-full flex items-center justify-center">
<div class="d-flex align-center"> <VBtn
<VAvatar size="40" color="primary" rounded variant="tonal" class="me-4"> v-show="hover.isHovering && currentUserIsSuperuser"
<VIcon size="24" icon="mdi-movie-open-outline"></VIcon> @click.stop="removeUser"
</VAvatar> icon="mdi-delete"
<div> color="error"
<div class="text-h6">{{ movieSubscriptions }}</div> size="small"
<div class="text-sm text-no-wrap">电影订阅</div> class="shadow-xl"
</div> />
</div> </div>
<div class="d-flex align-center"> </VCard>
<VAvatar size="40" color="primary" rounded variant="tonal" class="me-4"> </VHover>
<VIcon size="24" icon="mdi-television"></VIcon>
</VAvatar>
<div>
<div class="text-h6">{{ tvShowSubscriptions }}</div>
<div class="text-sm text-no-wrap">电视剧订阅</div>
</div>
</div>
</VCardText>
<VCardText class="pb-6">
<VDivider class="my-2">
<h5 class="text-h6">详情</h5>
</VDivider>
<VList lines="one">
<VListItem>
<VListItemTitle class="text-sm">
<span class="font-weight-medium">邮箱</span><span class="text-body-1"> {{ user.email }}</span>
</VListItemTitle>
</VListItem>
<VListItem>
<VListItemTitle class="text-sm">
<span class="font-weight-medium">状态</span
><span class="text-body-1">
<VChip size="small" :class="{ 'text-success': user.is_active }" variant="tonal">
{{ user.is_active ? '激活' : '已停用' }}
</VChip>
</span>
</VListItemTitle>
</VListItem>
<VListItem>
<VListItemTitle class="text-sm">
<span class="font-weight-medium">双重认证</span
><span class="text-body-1">
<VChip size="small" :class="{ 'text-success': user.is_otp }" variant="tonal">
{{ user.is_otp ? '已启用' : '未启用' }}
</VChip>
</span>
</VListItemTitle>
</VListItem>
</VList>
</VCardText>
<VCardText class="flex flex-row justify-center">
<VBtn v-if="currentUserIsSuperuser" color="primary" class="me-4" @click="editUser"> 编辑 </VBtn>
<VBtn
v-if="currentUserIsSuperuser && props.user.id != currentLoginUserId"
color="error"
variant="outlined"
@click="removeUser"
>
删除
</VBtn>
</VCardText>
</VCard>
<!-- 用户编辑弹窗 --> <!-- 用户编辑弹窗 -->
<UserAddEditDialog <UserAddEditDialog
v-if="userEditDialog" v-if="userEditDialog"
v-model="userEditDialog" v-model="userEditDialog"
:username="props.user?.name" :username="user?.name"
:usernames="props.users.map(item => item.name)" :usernames="users.map(item => item.name)"
oper="edit" oper="edit"
@save="onUserUpdate" @save="onUserUpdate"
@close="userEditDialog = false" @close="userEditDialog = false"
/> />
</template> </template>
<style scoped>
.img-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.5);
z-index: 1;
}
</style>
+129 -120
View File
@@ -172,132 +172,141 @@ const resolveProgress = (item: Workflow) => {
</script> </script>
<template> <template>
<div class="h-full"> <div class="h-full">
<VCard class="mx-auto h-full" @click="handleFlow(workflow)" :ripple="false" :loading="loading"> <VHover v-slot="hover">
<VCardItem class="py-3" :class="`bg-${resolveStatusVariant(workflow?.state).color}`"> <VCard
<template #prepend> v-bind="hover.props"
<VAvatar variant="text" class="me-2"> class="mx-auto h-full"
<VIcon @click="handleFlow(workflow)"
v-if="workflow?.state === 'P'" :ripple="false"
color="success" :loading="loading"
size="x-large" :class="{ 'transition transform-cpu duration-300 -translate-y-1': hover.isHovering }"
icon="mdi-play" >
@click.stop="handleEnable(workflow)" <VCardItem class="py-3" :class="`bg-${resolveStatusVariant(workflow?.state).color}`">
/> <template #prepend>
<VIcon v-else color="warning" icon="mdi-pause" size="x-large" @click.stop="handlePause(workflow)" /> <VAvatar variant="text" class="me-2">
</VAvatar> <VIcon
</template> v-if="workflow?.state === 'P'"
<VCardTitle class="text-white"> color="success"
{{ workflow?.name }} size="x-large"
</VCardTitle> icon="mdi-play"
<VCardSubtitle class="text-white">{{ workflow?.description }}</VCardSubtitle> @click.stop="handleEnable(workflow)"
<template #append> />
<IconBtn> <VIcon v-else color="warning" icon="mdi-pause" size="x-large" @click.stop="handlePause(workflow)" />
<VIcon icon="mdi-vector-polyline-edit" @click.stop="handleFlow(workflow)" /> </VAvatar>
</IconBtn> </template>
<IconBtn> <VCardTitle class="text-white">
<VIcon icon="mdi-dots-vertical" /> {{ workflow?.name }}
<VMenu activator="parent" close-on-content-click> </VCardTitle>
<VList> <VCardSubtitle class="text-white">{{ workflow?.description }}</VCardSubtitle>
<VListItem variant="plain" base-color="primary" @click="handleEdit(workflow)"> <template #append>
<template #prepend> <IconBtn>
<VIcon icon="mdi-note-edit" /> <VIcon icon="mdi-vector-polyline-edit" @click.stop="handleFlow(workflow)" />
</template> </IconBtn>
<VListItemTitle>编辑任务</VListItemTitle> <IconBtn>
</VListItem> <VIcon icon="mdi-dots-vertical" />
<VListItem <VMenu activator="parent" close-on-content-click>
v-if="workflow.current_action" <VList>
variant="plain" <VListItem variant="plain" base-color="primary" @click="handleEdit(workflow)">
base-color="info" <template #prepend>
@click="handleRun(workflow, false)" <VIcon icon="mdi-note-edit" />
> </template>
<template #prepend> <VListItemTitle>编辑任务</VListItemTitle>
<VIcon icon="mdi-play-speed" /> </VListItem>
</template> <VListItem
<VListItemTitle>继续执行</VListItemTitle> v-if="workflow.current_action"
</VListItem> variant="plain"
<VListItem base-color="info"
v-if="workflow.current_action" @click="handleRun(workflow, false)"
variant="plain" >
base-color="info" <template #prepend>
@click="handleRun(workflow, true)" <VIcon icon="mdi-play-speed" />
> </template>
<template #prepend> <VListItemTitle>继续执行</VListItemTitle>
<VIcon icon="mdi-replay" /> </VListItem>
</template> <VListItem
<VListItemTitle>重新执行</VListItemTitle> v-if="workflow.current_action"
</VListItem> variant="plain"
<VListItem v-else variant="plain" base-color="info" @click="handleRun(workflow, true)"> base-color="info"
<template #prepend> @click="handleRun(workflow, true)"
<VIcon icon="mdi-run" /> >
</template> <template #prepend>
<VListItemTitle>立即执行</VListItemTitle> <VIcon icon="mdi-replay" />
</VListItem> </template>
<VListItem variant="plain" base-color="warning" @click="handleReset(workflow)"> <VListItemTitle>重新执行</VListItemTitle>
<template #prepend> </VListItem>
<VIcon icon="mdi-restore-alert" /> <VListItem v-else variant="plain" base-color="info" @click="handleRun(workflow, true)">
</template> <template #prepend>
<VListItemTitle>重置任务</VListItemTitle> <VIcon icon="mdi-run" />
</VListItem> </template>
<VListItem variant="plain" base-color="error" @click="handleDelete(workflow)"> <VListItemTitle>立即执行</VListItemTitle>
<template #prepend> </VListItem>
<VIcon icon="mdi-delete" /> <VListItem variant="plain" base-color="warning" @click="handleReset(workflow)">
</template> <template #prepend>
<VListItemTitle>删除任务</VListItemTitle> <VIcon icon="mdi-restore-alert" />
</VListItem> </template>
</VList> <VListItemTitle>重置任务</VListItemTitle>
</VMenu> </VListItem>
</IconBtn> <VListItem variant="plain" base-color="error" @click="handleDelete(workflow)">
</template> <template #prepend>
</VCardItem> <VIcon icon="mdi-delete" />
<VDivider /> </template>
<VCardText> <VListItemTitle>删除任务</VListItemTitle>
<div class="d-flex flex-column gap-y-4"> </VListItem>
<div class="d-flex flex-wrap gap-x-6"> </VList>
<div class="flex-1"> </VMenu>
<div class="mb-1">定时</div> </IconBtn>
<h5 class="text-h6">{{ workflow?.timer }}</h5> </template>
</div> </VCardItem>
<div class="flex-1"> <VDivider />
<div class="mb-1">状态</div> <VCardText>
<h5 class="text-h6" :class="`text-${resolveStatusVariant(workflow?.state).color}`"> <div class="d-flex flex-column gap-y-4">
{{ resolveStatusVariant(workflow?.state).text }} <div class="d-flex flex-wrap gap-x-6">
</h5> <div class="flex-1">
</div> <div class="mb-1">定时</div>
</div> <h5 class="text-h6">{{ workflow?.timer }}</h5>
<div class="d-flex flex-wrap gap-x-6"> </div>
<div class="flex-1"> <div class="flex-1">
<div class="mb-1">动作数</div> <div class="mb-1">状态</div>
<div> <h5 class="text-h6" :class="`text-${resolveStatusVariant(workflow?.state).color}`">
<VAvatar size="32" color="primary" variant="tonal"> {{ resolveStatusVariant(workflow?.state).text }}
<span class="text-sm">{{ workflow?.actions?.length }}</span> </h5>
</VAvatar>
</div> </div>
</div> </div>
<div class="flex-1"> <div class="d-flex flex-wrap gap-x-6">
<div class="mb-1">已执行次数</div> <div class="flex-1">
<h5 class="text-h6">{{ workflow?.run_count }}</h5> <div class="mb-1">动作数</div>
</div> <div>
</div> <VAvatar size="32" color="primary" variant="tonal">
<div class="d-flex flex-wrap gap-x-6"> <span class="text-sm">{{ workflow?.actions?.length }}</span>
<div class="flex-1"> </VAvatar>
<div class="mb-1">进度</div>
<div class="d-flex align-center gap-5">
<div class="flex-grow-1">
<VProgressLinear color="info" rounded :model-value="resolveProgress(workflow)" />
</div> </div>
<span> {{ resolveProgress(workflow) }}% </span> </div>
<div class="flex-1">
<div class="mb-1">已执行次数</div>
<h5 class="text-h6">{{ workflow?.run_count }}</h5>
</div>
</div>
<div class="d-flex flex-wrap gap-x-6">
<div class="flex-1">
<div class="mb-1">进度</div>
<div class="d-flex align-center gap-5">
<div class="flex-grow-1">
<VProgressLinear color="info" rounded :model-value="resolveProgress(workflow)" />
</div>
<span> {{ resolveProgress(workflow) }}% </span>
</div>
</div>
</div>
<div class="d-flex flex-wrap gap-x-6" v-if="workflow?.result">
<div class="flex-1">
<div class="mb-1">错误信息</div>
<div class="text-error">{{ workflow?.result }}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="d-flex flex-wrap gap-x-6" v-if="workflow?.result"> </VCardText>
<div class="flex-1"> </VCard>
<div class="mb-1">错误信息</div> </VHover>
<div class="text-error">{{ workflow?.result }}</div>
</div>
</div>
</div>
</VCardText>
</VCard>
<!-- 流程对话框 --> <!-- 流程对话框 -->
<WorkflowActionsDialog <WorkflowActionsDialog
v-if="flowDialog" v-if="flowDialog"
+1 -1
View File
@@ -218,7 +218,7 @@ html.v-overlay-scroll-blocked body {
} }
.grid-user-card { .grid-user-card {
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
padding-block-end: 1rem; padding-block-end: 1rem;
} }