mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-06 00:01:33 +08:00
仪表板组件支持拖动排序
This commit is contained in:
@@ -6,8 +6,14 @@ import api from '@/api'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const currentTheme = controlledComputed(() => vuetifyTheme.name.value, () => vuetifyTheme.current.value.colors)
|
||||
const variableTheme = controlledComputed(() => vuetifyTheme.name.value, () => vuetifyTheme.current.value.variables)
|
||||
const currentTheme = controlledComputed(
|
||||
() => vuetifyTheme.name.value,
|
||||
() => vuetifyTheme.current.value.colors,
|
||||
)
|
||||
const variableTheme = controlledComputed(
|
||||
() => vuetifyTheme.name.value,
|
||||
() => vuetifyTheme.current.value.variables,
|
||||
)
|
||||
|
||||
// 定时器
|
||||
let refreshTimer: NodeJS.Timer | null = null
|
||||
@@ -22,83 +28,86 @@ const series = ref([
|
||||
// 当前值
|
||||
const current = ref(0)
|
||||
|
||||
const chartOptions = controlledComputed(() => vuetifyTheme.name.value, () => {
|
||||
return {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
animations: { enabled: false },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
grid: {
|
||||
borderColor: `rgba(${hexToRgb(String(variableTheme.value['border-color']))},${variableTheme.value['border-opacity']})`,
|
||||
strokeDashArray: 6,
|
||||
const chartOptions = controlledComputed(
|
||||
() => vuetifyTheme.name.value,
|
||||
() => {
|
||||
return {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
animations: { enabled: false },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
grid: {
|
||||
borderColor: `rgba(${hexToRgb(String(variableTheme.value['border-color']))},${
|
||||
variableTheme.value['border-opacity']
|
||||
})`,
|
||||
strokeDashArray: 6,
|
||||
xaxis: {
|
||||
lines: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
lines: { show: true },
|
||||
},
|
||||
padding: {
|
||||
top: -10,
|
||||
left: -7,
|
||||
right: 5,
|
||||
bottom: 5,
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
width: 3,
|
||||
lineCap: 'butt',
|
||||
curve: 'smooth',
|
||||
},
|
||||
colors: [currentTheme.value.primary],
|
||||
markers: {
|
||||
size: 6,
|
||||
offsetY: 4,
|
||||
offsetX: -2,
|
||||
strokeWidth: 3,
|
||||
colors: ['transparent'],
|
||||
strokeColors: 'transparent',
|
||||
discrete: [
|
||||
{
|
||||
size: 5.5,
|
||||
seriesIndex: 0,
|
||||
strokeColor: currentTheme.value.primary,
|
||||
fillColor: currentTheme.value.surface,
|
||||
},
|
||||
],
|
||||
hover: { size: 7 },
|
||||
},
|
||||
xaxis: {
|
||||
lines: { show: false },
|
||||
labels: { show: false },
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
lines: { show: true },
|
||||
labels: { show: false },
|
||||
max: 100,
|
||||
},
|
||||
padding: {
|
||||
top: -10,
|
||||
left: -7,
|
||||
right: 5,
|
||||
bottom: 5,
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
width: 3,
|
||||
lineCap: 'butt',
|
||||
curve: 'smooth',
|
||||
},
|
||||
colors: [currentTheme.value.primary],
|
||||
markers: {
|
||||
size: 6,
|
||||
offsetY: 4,
|
||||
offsetX: -2,
|
||||
strokeWidth: 3,
|
||||
colors: ['transparent'],
|
||||
strokeColors: 'transparent',
|
||||
discrete: [
|
||||
{
|
||||
size: 5.5,
|
||||
seriesIndex: 0,
|
||||
strokeColor: currentTheme.value.primary,
|
||||
fillColor: currentTheme.value.surface,
|
||||
},
|
||||
],
|
||||
hover: { size: 7 },
|
||||
},
|
||||
xaxis: {
|
||||
labels: { show: false },
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
labels: { show: false },
|
||||
max: 100,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 调用API接口获取最新CPU使用率
|
||||
async function getCpuUsage() {
|
||||
try {
|
||||
// 请求数据
|
||||
current.value = await api.get('dashboard/cpu') ?? 0
|
||||
current.value = (await api.get('dashboard/cpu')) ?? 0
|
||||
// 添加到序列
|
||||
series.value[0].data.push(current.value)
|
||||
// 序列超过30条记录时,清掉前面的
|
||||
if (series.value[0].data.length > 30)
|
||||
series.value[0].data.shift()
|
||||
}
|
||||
catch (e) {
|
||||
if (series.value[0].data.length > 30) series.value[0].data.shift()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCpuUsage()// 启动定时器
|
||||
getCpuUsage() // 启动定时器
|
||||
refreshTimer = setInterval(() => {
|
||||
getCpuUsage()
|
||||
}, 2000)
|
||||
@@ -115,20 +124,13 @@ onUnmounted(() => {
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle class="cursor-move">CPU</VCardTitle>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<h6 class="text-h6">
|
||||
CPU
|
||||
</h6>
|
||||
<VueApexCharts
|
||||
type="line"
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="150"
|
||||
/>
|
||||
<VueApexCharts type="line" :options="chartOptions" :series="series" :height="150" />
|
||||
|
||||
<p class="text-center font-weight-medium mb-0">
|
||||
当前:{{ current }}%
|
||||
</p>
|
||||
<p class="text-center font-weight-medium mb-0">当前:{{ current }}%</p>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -42,8 +42,7 @@ async function loadMediaStatistic() {
|
||||
color: 'info',
|
||||
},
|
||||
]
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -56,29 +55,16 @@ onMounted(() => {
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>媒体统计</VCardTitle>
|
||||
<VCardTitle class="cursor-move">媒体统计</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
v-for="item in statistics"
|
||||
:key="item.title"
|
||||
cols="6"
|
||||
sm="3"
|
||||
>
|
||||
<VCol v-for="item in statistics" :key="item.title" cols="6" sm="3">
|
||||
<div class="d-flex align-center">
|
||||
<div class="me-3">
|
||||
<VAvatar
|
||||
:color="item.color"
|
||||
rounded
|
||||
size="42"
|
||||
class="elevation-1"
|
||||
>
|
||||
<VIcon
|
||||
size="24"
|
||||
:icon="item.icon"
|
||||
/>
|
||||
<VAvatar :color="item.color" rounded size="42" class="elevation-1">
|
||||
<VIcon size="24" :icon="item.icon" />
|
||||
</VAvatar>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -7,8 +7,14 @@ import { formatBytes } from '@/@core/utils/formatters'
|
||||
|
||||
const vuetifyTheme = useTheme()
|
||||
|
||||
const currentTheme = controlledComputed(() => vuetifyTheme.name.value, () => vuetifyTheme.current.value.colors)
|
||||
const variableTheme = controlledComputed(() => vuetifyTheme.name.value, () => vuetifyTheme.current.value.variables)
|
||||
const currentTheme = controlledComputed(
|
||||
() => vuetifyTheme.name.value,
|
||||
() => vuetifyTheme.current.value.colors,
|
||||
)
|
||||
const variableTheme = controlledComputed(
|
||||
() => vuetifyTheme.name.value,
|
||||
() => vuetifyTheme.current.value.variables,
|
||||
)
|
||||
|
||||
// 定时器
|
||||
let refreshTimer: NodeJS.Timer | null = null
|
||||
@@ -25,79 +31,82 @@ const usedMemory = ref(0)
|
||||
// 内存使用百分比
|
||||
const memoryUsage = ref(0)
|
||||
|
||||
const chartOptions = controlledComputed(() => vuetifyTheme.name.value, () => {
|
||||
return {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
animations: { enabled: false },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
grid: {
|
||||
borderColor: `rgba(${hexToRgb(String(variableTheme.value['border-color']))},${variableTheme.value['border-opacity']})`,
|
||||
strokeDashArray: 6,
|
||||
const chartOptions = controlledComputed(
|
||||
() => vuetifyTheme.name.value,
|
||||
() => {
|
||||
return {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
toolbar: { show: false },
|
||||
animations: { enabled: false },
|
||||
},
|
||||
tooltip: { enabled: false },
|
||||
grid: {
|
||||
borderColor: `rgba(${hexToRgb(String(variableTheme.value['border-color']))},${
|
||||
variableTheme.value['border-opacity']
|
||||
})`,
|
||||
strokeDashArray: 6,
|
||||
xaxis: {
|
||||
lines: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
lines: { show: true },
|
||||
},
|
||||
padding: {
|
||||
top: -10,
|
||||
left: -7,
|
||||
right: 5,
|
||||
bottom: 5,
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
width: 3,
|
||||
lineCap: 'butt',
|
||||
curve: 'smooth',
|
||||
},
|
||||
colors: [currentTheme.value.primary],
|
||||
markers: {
|
||||
size: 6,
|
||||
offsetY: 4,
|
||||
offsetX: -2,
|
||||
strokeWidth: 3,
|
||||
colors: ['transparent'],
|
||||
strokeColors: 'transparent',
|
||||
discrete: [
|
||||
{
|
||||
size: 5.5,
|
||||
seriesIndex: 0,
|
||||
strokeColor: currentTheme.value.primary,
|
||||
fillColor: currentTheme.value.surface,
|
||||
},
|
||||
],
|
||||
hover: { size: 7 },
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
xaxis: {
|
||||
lines: { show: false },
|
||||
labels: { show: false },
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
lines: { show: true },
|
||||
labels: { show: false },
|
||||
max: 100,
|
||||
},
|
||||
padding: {
|
||||
top: -10,
|
||||
left: -7,
|
||||
right: 5,
|
||||
bottom: 5,
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
width: 3,
|
||||
lineCap: 'butt',
|
||||
curve: 'smooth',
|
||||
},
|
||||
colors: [currentTheme.value.primary],
|
||||
markers: {
|
||||
size: 6,
|
||||
offsetY: 4,
|
||||
offsetX: -2,
|
||||
strokeWidth: 3,
|
||||
colors: ['transparent'],
|
||||
strokeColors: 'transparent',
|
||||
discrete: [
|
||||
{
|
||||
size: 5.5,
|
||||
seriesIndex: 0,
|
||||
strokeColor: currentTheme.value.primary,
|
||||
fillColor: currentTheme.value.surface,
|
||||
},
|
||||
],
|
||||
hover: { size: 7 },
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
xaxis: {
|
||||
labels: { show: false },
|
||||
axisTicks: { show: false },
|
||||
axisBorder: { show: false },
|
||||
},
|
||||
yaxis: {
|
||||
labels: { show: false },
|
||||
max: 100,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 调用API接口获取最新内存使用量
|
||||
async function getMemorgUsage() {
|
||||
try {
|
||||
// 请求数据
|
||||
[usedMemory.value, memoryUsage.value] = await api.get('dashboard/memory')
|
||||
;[usedMemory.value, memoryUsage.value] = await api.get('dashboard/memory')
|
||||
series.value[0].data.push(memoryUsage.value)
|
||||
// 序列超过30条记录时,清掉前面的
|
||||
if (series.value[0].data.length > 30)
|
||||
series.value[0].data.shift()
|
||||
}
|
||||
catch (e) {
|
||||
if (series.value[0].data.length > 30) series.value[0].data.shift()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -121,20 +130,13 @@ onUnmounted(() => {
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle class="cursor-move">内存</VCardTitle>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<h6 class="text-h6">
|
||||
内存
|
||||
</h6>
|
||||
<VueApexCharts
|
||||
type="area"
|
||||
:options="chartOptions"
|
||||
:series="series"
|
||||
:height="150"
|
||||
/>
|
||||
<VueApexCharts type="area" :options="chartOptions" :series="series" :height="150" />
|
||||
|
||||
<p class="text-center font-weight-medium mb-0">
|
||||
当前:{{ formatBytes(usedMemory) }}
|
||||
</p>
|
||||
<p class="text-center font-weight-medium mb-0">当前:{{ formatBytes(usedMemory) }}</p>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -18,8 +18,7 @@ async function loadProcessList() {
|
||||
const res: Process[] = await api.get('dashboard/processes')
|
||||
|
||||
processList.value = res
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -43,47 +42,29 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="系统进程">
|
||||
<VTable
|
||||
item-key="fullName"
|
||||
class="table-rounded"
|
||||
hide-default-footer
|
||||
disable-sort
|
||||
>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle class="cursor-move">系统进程</VCardTitle>
|
||||
</VCardItem>
|
||||
<VTable item-key="fullName" class="table-rounded" hide-default-footer disable-sort>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
v-for="header in headers"
|
||||
:id="header"
|
||||
:key="header"
|
||||
>
|
||||
<th v-for="header in headers" :id="header" :key="header">
|
||||
{{ header }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="row in processList"
|
||||
:key="row.pid"
|
||||
>
|
||||
<td
|
||||
class="text-sm"
|
||||
v-text="row.pid"
|
||||
/>
|
||||
<tr v-for="row in processList" :key="row.pid">
|
||||
<td class="text-sm" v-text="row.pid" />
|
||||
<!-- name -->
|
||||
<td>
|
||||
<h6 class="text-sm font-weight-medium">
|
||||
{{ row.name }}
|
||||
</h6>
|
||||
</td>
|
||||
<td
|
||||
class="text-sm"
|
||||
v-text="formatSeconds(row.run_time)"
|
||||
/>
|
||||
<td
|
||||
class="text-sm"
|
||||
v-text="`${row.memory} MB`"
|
||||
/>
|
||||
<td class="text-sm" v-text="formatSeconds(row.run_time)" />
|
||||
<td class="text-sm" v-text="`${row.memory} MB`" />
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
|
||||
@@ -14,8 +14,7 @@ async function loadSchedulerList() {
|
||||
const res: ScheduleInfo[] = await api.get('dashboard/schedule')
|
||||
|
||||
schedulerList.value = res
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -41,25 +40,14 @@ onUnmounted(() => {
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>后台任务</VCardTitle>
|
||||
<VCardTitle class="cursor-move">后台任务</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VList
|
||||
class="card-list"
|
||||
height="250"
|
||||
>
|
||||
<VListItem
|
||||
v-for="item in schedulerList"
|
||||
:key="item.id"
|
||||
>
|
||||
<VList class="card-list" height="250">
|
||||
<VListItem v-for="item in schedulerList" :key="item.id">
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="40"
|
||||
variant="tonal"
|
||||
color=""
|
||||
class="me-3"
|
||||
>
|
||||
<VAvatar size="40" variant="tonal" color="" class="me-3">
|
||||
{{ item.name[0] }}
|
||||
</VAvatar>
|
||||
</template>
|
||||
@@ -81,9 +69,7 @@ onUnmounted(() => {
|
||||
</template>
|
||||
</VListItem>
|
||||
<VListItem v-if="schedulerList.length === 0">
|
||||
<VListItemTitle class="text-center">
|
||||
没有后台服务
|
||||
</VListItemTitle>
|
||||
<VListItemTitle class="text-center"> 没有后台服务 </VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
|
||||
@@ -56,8 +56,7 @@ async function loadDownloaderInfo() {
|
||||
amount: formatFileSize(res.free_space),
|
||||
},
|
||||
]
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -83,28 +82,18 @@ onUnmounted(() => {
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>实时速率</VCardTitle>
|
||||
<VCardTitle class="cursor-move">实时速率</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText class="pt-4">
|
||||
<div>
|
||||
<p class="text-h5 me-2">
|
||||
↑{{ formatFileSize(downloadInfo.upload_speed) }}/s
|
||||
</p>
|
||||
<p class="text-h4 me-2">
|
||||
↓{{ formatFileSize(downloadInfo.download_speed) }}/s
|
||||
</p>
|
||||
<p class="text-h5 me-2">↑{{ formatFileSize(downloadInfo.upload_speed) }}/s</p>
|
||||
<p class="text-h4 me-2">↓{{ formatFileSize(downloadInfo.download_speed) }}/s</p>
|
||||
</div>
|
||||
<VList class="card-list mt-9">
|
||||
<VListItem
|
||||
v-for="item in infoItems"
|
||||
:key="item.title"
|
||||
>
|
||||
<VListItem v-for="item in infoItems" :key="item.title">
|
||||
<template #prepend>
|
||||
<VIcon
|
||||
rounded
|
||||
:icon="item.avatar"
|
||||
/>
|
||||
<VIcon rounded :icon="item.avatar" />
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="text-sm font-weight-medium mb-1">
|
||||
|
||||
@@ -8,9 +8,7 @@ import triangleLight from '@images/misc/triangle-light.png'
|
||||
|
||||
const { global } = useTheme()
|
||||
|
||||
const triangleBg = computed(() =>
|
||||
global.name.value === 'light' ? triangleLight : triangleDark,
|
||||
)
|
||||
const triangleBg = computed(() => (global.name.value === 'light' ? triangleLight : triangleDark))
|
||||
|
||||
// 总存储空间
|
||||
const storage = ref(0)
|
||||
@@ -30,8 +28,7 @@ async function getStorage() {
|
||||
|
||||
storage.value = res.total_storage
|
||||
used.value = res.used_storage
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -42,42 +39,30 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard
|
||||
title="存储空间"
|
||||
subtitle=""
|
||||
class="position-relative"
|
||||
>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle class="cursor-move">存储空间</VCardTitle>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<h5 class="text-2xl font-weight-medium text-primary">
|
||||
{{ formatFileSize(storage) }}
|
||||
</h5>
|
||||
<p class="mt-2">
|
||||
已使用 {{ usedPercent }}% 🚀
|
||||
</p>
|
||||
<p class="mt-2">已使用 {{ usedPercent }}% 🚀</p>
|
||||
<p class="mt-1">
|
||||
<VProgressLinear
|
||||
:model-value="usedPercent"
|
||||
color="primary"
|
||||
/>
|
||||
<VProgressLinear :model-value="usedPercent" color="primary" />
|
||||
</p>
|
||||
</VCardText>
|
||||
|
||||
<!-- Triangle Background -->
|
||||
<VImg
|
||||
:src="triangleBg"
|
||||
class="triangle-bg flip-in-rtl"
|
||||
/>
|
||||
<VImg :src="triangleBg" class="triangle-bg flip-in-rtl" />
|
||||
|
||||
<!-- Trophy -->
|
||||
<VImg
|
||||
:src="trophy"
|
||||
class="trophy"
|
||||
/>
|
||||
<VImg :src="trophy" class="trophy" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use "@layouts/styles/mixins" as layoutsMixins;
|
||||
@use '@layouts/styles/mixins' as layoutsMixins;
|
||||
|
||||
.v-card .triangle-bg {
|
||||
position: absolute;
|
||||
|
||||
@@ -80,8 +80,7 @@ const options = controlledComputed(
|
||||
fontSize: '12px',
|
||||
},
|
||||
|
||||
formatter: (value: number) =>
|
||||
value > 999 ? (value / 1000).toFixed(0) : value,
|
||||
formatter: (value: number) => (value > 999 ? (value / 1000).toFixed(0) : value),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -100,8 +99,7 @@ async function getWeeklyData() {
|
||||
const res: number[] = await api.get('dashboard/transfer')
|
||||
|
||||
series.value = [{ data: res }]
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -114,16 +112,11 @@ onMounted(() => {
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>最近入库</VCardTitle>
|
||||
<VCardTitle class="cursor-move">最近入库</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VueApexCharts
|
||||
type="bar"
|
||||
:options="options"
|
||||
:series="series"
|
||||
:height="160"
|
||||
/>
|
||||
<VueApexCharts type="bar" :options="options" :series="series" :height="160" />
|
||||
|
||||
<div class="d-flex align-center mb-3">
|
||||
<h5 class="text-h5 me-4">
|
||||
@@ -132,13 +125,7 @@ onMounted(() => {
|
||||
<p>最近一周入库了 {{ totalCount }} 部影片 😎</p>
|
||||
</div>
|
||||
|
||||
<VBtn
|
||||
v-if="superUser"
|
||||
block
|
||||
to="/history"
|
||||
>
|
||||
查看详情
|
||||
</VBtn>
|
||||
<VBtn v-if="superUser" block to="/history"> 查看详情 </VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -10,8 +10,7 @@ const latestList = ref<MediaServerPlayItem[]>([])
|
||||
async function loadLatest() {
|
||||
try {
|
||||
latestList.value = await api.get('mediaserver/latest')
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -24,19 +23,11 @@ onMounted(() => {
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>最近添加</VCardTitle>
|
||||
<VCardTitle class="cursor-move">最近添加</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<div
|
||||
v-if="latestList.length > 0"
|
||||
class="grid gap-4 grid-media-card mx-3 mb-3"
|
||||
tabindex="0"
|
||||
>
|
||||
<PosterCard
|
||||
v-for="data in latestList"
|
||||
:key="data.id"
|
||||
:media="data"
|
||||
/>
|
||||
<div v-if="latestList.length > 0" class="grid gap-4 grid-media-card mx-3 mb-3" tabindex="0">
|
||||
<PosterCard v-for="data in latestList" :key="data.id" :media="data" />
|
||||
</div>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -10,8 +10,7 @@ const libraryList = ref<MediaServerPlayItem[]>([])
|
||||
async function loadLibrary() {
|
||||
try {
|
||||
libraryList.value = await api.get('mediaserver/library')
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -24,20 +23,11 @@ onMounted(() => {
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>我的媒体库</VCardTitle>
|
||||
<VCardTitle class="cursor-move">我的媒体库</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<div
|
||||
v-if="libraryList.length > 0"
|
||||
class="grid gap-4 grid-backdrop-card mx-3"
|
||||
tabindex="0"
|
||||
>
|
||||
<LibraryCard
|
||||
v-for="data in libraryList"
|
||||
:key="data.id"
|
||||
:media="data"
|
||||
height="10rem"
|
||||
/>
|
||||
<div v-if="libraryList.length > 0" class="grid gap-4 grid-backdrop-card mx-3" tabindex="0">
|
||||
<LibraryCard v-for="data in libraryList" :key="data.id" :media="data" height="10rem" />
|
||||
</div>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -10,8 +10,7 @@ const playingList = ref<MediaServerPlayItem[]>([])
|
||||
async function loadPlayingList() {
|
||||
try {
|
||||
playingList.value = await api.get('mediaserver/playing')
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
@@ -24,20 +23,11 @@ onMounted(() => {
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem>
|
||||
<VCardTitle>继续观看</VCardTitle>
|
||||
<VCardTitle class="cursor-move">继续观看</VCardTitle>
|
||||
</VCardItem>
|
||||
|
||||
<div
|
||||
v-if="playingList.length > 0"
|
||||
class="grid gap-4 grid-backdrop-card mx-3"
|
||||
tabindex="0"
|
||||
>
|
||||
<BackdropCard
|
||||
v-for="data in playingList"
|
||||
:key="data.id"
|
||||
:media="data"
|
||||
height="10rem"
|
||||
/>
|
||||
<div v-if="playingList.length > 0" class="grid gap-4 grid-backdrop-card mx-3" tabindex="0">
|
||||
<BackdropCard v-for="data in playingList" :key="data.id" :media="data" height="10rem" />
|
||||
</div>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user