refactor: 优化站点卡片组件

This commit is contained in:
jxxghp
2024-10-17 21:39:26 +08:00
parent b3485af14c
commit 7973457417
2 changed files with 47 additions and 16 deletions
+16 -6
View File
@@ -6,15 +6,15 @@ import SiteUserDataDialog from '../dialog/SiteUserDataDialog.vue'
import SiteResourceDialog from '../dialog/SiteResourceDialog.vue' import SiteResourceDialog from '../dialog/SiteResourceDialog.vue'
import SiteCookieUpdateDialog from '../dialog/SiteCookieUpdateDialog.vue' import SiteCookieUpdateDialog from '../dialog/SiteCookieUpdateDialog.vue'
import api from '@/api' import api from '@/api'
import type { Site, SiteStatistic } from '@/api/types' import type { Site, SiteStatistic, SiteUserData } from '@/api/types'
import { isNullOrEmptyObject } from '@/@core/utils' import { isNullOrEmptyObject } from '@/@core/utils'
import { VCardActions, VExpandTransition, VSpacer } from 'vuetify/lib/components/index.mjs' import { VCardActions, VExpandTransition, VProgressLinear, VSpacer } from 'vuetify/lib/components/index.mjs'
import { formatFileSize } from '@/@core/utils/formatters'
// 输入参数 // 输入参数
const cardProps = defineProps({ const cardProps = defineProps({
site: Object as PropType<Site>, site: Object as PropType<Site>,
width: String, data: Object as PropType<SiteUserData>,
height: String,
}) })
// 定义触发的自定义事件 // 定义触发的自定义事件
@@ -121,6 +121,12 @@ const statColor = computed(() => {
} }
}) })
// 计算上传量和下载量的百分比
const getPercentage = computed(() => {
if (cardProps.data?.upload === 0) return 100
return ((cardProps.data?.download ?? 0) / ((cardProps.data?.download ?? 0) + (cardProps.data?.upload ?? 0))) * 100
})
// 保存站点 // 保存站点
function saveSite() { function saveSite() {
siteEditDialog.value = false siteEditDialog.value = false
@@ -149,8 +155,6 @@ onMounted(() => {
<template> <template>
<div> <div>
<VCard <VCard
:height="cardProps.height"
:width="cardProps.width"
:variant="cardProps.site?.is_active ? 'elevated' : 'outlined'" :variant="cardProps.site?.is_active ? 'elevated' : 'outlined'"
class="overflow-hidden" class="overflow-hidden"
@click="siteEditDialog = true" @click="siteEditDialog = true"
@@ -195,6 +199,9 @@ onMounted(() => {
:icon="siteActionShow ? 'mdi-chevron-up' : 'mdi-chevron-down'" :icon="siteActionShow ? 'mdi-chevron-up' : 'mdi-chevron-down'"
@click.stop="siteActionShow = !siteActionShow" @click.stop="siteActionShow = !siteActionShow"
/> />
<span class="text-sm">
{{ formatFileSize(cardProps.data?.upload || 0) }} / {{ formatFileSize(cardProps.data?.download || 0) }}
</span>
<VSpacer /> <VSpacer />
</VCardActions> </VCardActions>
<VDivider class="mb-1" v-if="siteActionShow" /> <VDivider class="mb-1" v-if="siteActionShow" />
@@ -230,6 +237,9 @@ onMounted(() => {
<span class="absolute top-1 right-8"> <span class="absolute top-1 right-8">
<VIcon class="cursor-move">mdi-drag</VIcon> <VIcon class="cursor-move">mdi-drag</VIcon>
</span> </span>
<div class="w-full absolute bottom-0" v-if="(cardProps.data?.upload || cardProps.data?.download || 0) > 0">
<VProgressLinear :model-value="getPercentage" bg-color="success" color="warning" bg-opacity="0.5" height="3" />
</div>
</VCard> </VCard>
<!-- 更新站点Cookie & UA弹窗 --> <!-- 更新站点Cookie & UA弹窗 -->
<SiteCookieUpdateDialog <SiteCookieUpdateDialog
+31 -10
View File
@@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
import api from '@/api' import api from '@/api'
import type { Site } from '@/api/types' import type { Site, SiteUserData } from '@/api/types'
import SiteCard from '@/components/cards/SiteCard.vue' import SiteCard from '@/components/cards/SiteCard.vue'
import NoDataFound from '@/components/NoDataFound.vue' import NoDataFound from '@/components/NoDataFound.vue'
import SiteAddEditDialog from '@/components/dialog/SiteAddEditDialog.vue' import SiteAddEditDialog from '@/components/dialog/SiteAddEditDialog.vue'
@@ -15,8 +15,11 @@ const appMode = computed(() => {
return localStorage.getItem('MP_APPMODE') != '0' && display.mdAndDown.value return localStorage.getItem('MP_APPMODE') != '0' && display.mdAndDown.value
}) })
// 数据列表 // 站点列表
const dataList = ref<Site[]>([]) const siteList = ref<Site[]>([])
// 站点数据列表
const userDataList = ref<SiteUserData[]>([])
// 是否刷新过 // 是否刷新过
const isRefreshed = ref(false) const isRefreshed = ref(false)
@@ -31,7 +34,7 @@ const siteAddDialog = ref(false)
async function fetchData() { async function fetchData() {
try { try {
loading.value = true loading.value = true
dataList.value = await api.get('site/') siteList.value = await api.get('site/')
loading.value = false loading.value = false
isRefreshed.value = true isRefreshed.value = true
} catch (error) { } catch (error) {
@@ -39,10 +42,19 @@ async function fetchData() {
} }
} }
// 获取站点最新数据
async function fetchUserData() {
try {
userDataList.value = await api.get('site/userdata/latest')
} catch (error) {
console.error(error)
}
}
// 保存站点排序 // 保存站点排序
async function savaSitesPriority() { async function savaSitesPriority() {
// 重新排序 // 重新排序
const priorities = dataList.value.map((site, index) => ({ id: site.id, pri: index + 1 })) const priorities = siteList.value.map((site, index) => ({ id: site.id, pri: index + 1 }))
try { try {
const result: { [key: string]: any } = await api.post('site/priorities', priorities) const result: { [key: string]: any } = await api.post('site/priorities', priorities)
if (result.success) { if (result.success) {
@@ -53,6 +65,11 @@ async function savaSitesPriority() {
} }
} }
// 根据站点ID获取站点数据
function getUserData(domain: string) {
return userDataList.value.find(userData => userData.domain === domain)
}
// 更新站点事件时 // 更新站点事件时
function onSiteSave() { function onSiteSave() {
siteAddDialog.value = false siteAddDialog.value = false
@@ -60,11 +77,15 @@ function onSiteSave() {
} }
// 加载时获取数据 // 加载时获取数据
onBeforeMount(fetchData) onBeforeMount(() => {
fetchData()
fetchUserData()
})
onActivated(() => { onActivated(() => {
if (!loading.value) { if (!loading.value) {
fetchData() fetchData()
fetchUserData()
} }
}) })
</script> </script>
@@ -73,8 +94,8 @@ onActivated(() => {
<LoadingBanner v-if="!isRefreshed" class="mt-12" /> <LoadingBanner v-if="!isRefreshed" class="mt-12" />
<div> <div>
<draggable <draggable
v-if="dataList.length > 0" v-if="siteList.length > 0"
v-model="dataList" v-model="siteList"
@end="savaSitesPriority" @end="savaSitesPriority"
handle=".cursor-move" handle=".cursor-move"
item-key="id" item-key="id"
@@ -82,12 +103,12 @@ onActivated(() => {
:component-data="{ 'class': 'grid gap-3 grid-site-card' }" :component-data="{ 'class': 'grid gap-3 grid-site-card' }"
> >
<template #item="{ element }"> <template #item="{ element }">
<SiteCard :site="element" @remove="fetchData" @update="fetchData" /> <SiteCard :site="element" :data="getUserData(element.domain)" @remove="fetchData" @update="fetchData" />
</template> </template>
</draggable> </draggable>
</div> </div>
<NoDataFound <NoDataFound
v-if="dataList.length === 0 && isRefreshed" v-if="siteList.length === 0 && isRefreshed"
error-code="404" error-code="404"
error-title="没有站点" error-title="没有站点"
error-description="已添加并支持的站点将会在这里显示" error-description="已添加并支持的站点将会在这里显示"