es lint fix

This commit is contained in:
thofx
2023-07-22 16:09:07 +08:00
parent 48749b29fe
commit 018778488a
80 changed files with 3994 additions and 2981 deletions
+45 -30
View File
@@ -1,54 +1,56 @@
<script setup lang="ts">
import api from "@/api";
import { MediaStatistic } from "@/api/types";
import api from '@/api'
import type { MediaStatistic } from '@/api/types'
const statistics = ref([
{
title: "",
stats: "",
icon: "",
color: "",
title: '',
stats: '',
icon: '',
color: '',
},
]);
])
// 调用API加载媒体统计数据
const loadMediaStatistic = async () => {
async function loadMediaStatistic() {
try {
const res: MediaStatistic = await api.get("dashboard/statistic");
const res: MediaStatistic = await api.get('dashboard/statistic')
statistics.value = [
{
title: "电影",
title: '电影',
stats: res.movie_count.toLocaleString(),
icon: "mdi-movie-roll",
color: "primary",
icon: 'mdi-movie-roll',
color: 'primary',
},
{
title: "电视剧",
title: '电视剧',
stats: res.tv_count.toLocaleString(),
icon: "mdi-television-box",
color: "success",
icon: 'mdi-television-box',
color: 'success',
},
{
title: "剧集",
title: '剧集',
stats: res.episode_count.toLocaleString(),
icon: "mdi-television-classic",
color: "warning",
icon: 'mdi-television-classic',
color: 'warning',
},
{
title: "用户",
title: '用户',
stats: res.user_count.toLocaleString(),
icon: "mdi-account",
color: "info",
icon: 'mdi-account',
color: 'info',
},
];
} catch (e) {
console.log(e);
]
}
};
catch (e) {
console.log(e)
}
}
onMounted(() => {
loadMediaStatistic();
});
loadMediaStatistic()
})
</script>
<template>
@@ -59,11 +61,24 @@ onMounted(() => {
<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>
+46 -25
View File
@@ -1,42 +1,45 @@
<script lang="ts" setup>
import { formatSeconds } from "@/@core/utils/formatters";
import api from "@/api";
import { Process } from "@/api/types";
import { formatSeconds } from '@/@core/utils/formatters'
import api from '@/api'
import type { Process } from '@/api/types'
// 表头
const headers = ["进程ID", "进程名称", "运行时间", "内存占用"];
const headers = ['进程ID', '进程名称', '运行时间', '内存占用']
// 数据列表
const processList = ref<Process[]>([]);
const processList = ref<Process[]>([])
// 定时器
let refreshTimer: NodeJS.Timer | null = null;
let refreshTimer: NodeJS.Timer | null = null
// 调用API加载数据
const loadProcessList = async () => {
async function loadProcessList() {
try {
const res: Process[] = await api.get("dashboard/processes");
processList.value = res;
} catch (e) {
console.log(e);
const res: Process[] = await api.get('dashboard/processes')
processList.value = res
}
};
catch (e) {
console.log(e)
}
}
onMounted(() => {
loadProcessList();
loadProcessList()
// 启动定时器
refreshTimer = setInterval(() => {
loadProcessList();
}, 5000);
});
loadProcessList()
}, 5000)
})
// 组件卸载时停止定时器
onUnmounted(() => {
if (refreshTimer) {
clearInterval(refreshTimer);
refreshTimer = null;
clearInterval(refreshTimer)
refreshTimer = null
}
});
})
</script>
<template>
@@ -51,20 +54,38 @@ onUnmounted(() => {
>
<thead>
<tr>
<th v-for="header in headers" :key="header" :id="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>
<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>
+40 -22
View File
@@ -1,38 +1,41 @@
<script setup lang="ts">
import api from "@/api";
import { ScheduleInfo } from "@/api/types";
import api from '@/api'
import type { ScheduleInfo } from '@/api/types'
// 定时服务列表
const schedulerList = ref<ScheduleInfo[]>([]);
const schedulerList = ref<ScheduleInfo[]>([])
// 定时器
let refreshTimer: NodeJS.Timer | null = null;
let refreshTimer: NodeJS.Timer | null = null
// 调用API加载定时服务列表
const loadSchedulerList = async () => {
async function loadSchedulerList() {
try {
const res: ScheduleInfo[] = await api.get("dashboard/schedule");
schedulerList.value = res;
} catch (e) {
console.log(e);
const res: ScheduleInfo[] = await api.get('dashboard/schedule')
schedulerList.value = res
}
};
catch (e) {
console.log(e)
}
}
onMounted(() => {
loadSchedulerList();
loadSchedulerList()
// 启动定时器
refreshTimer = setInterval(() => {
loadSchedulerList();
}, 60000);
});
loadSchedulerList()
}, 60000)
})
// 组件卸载时停止定时器
onUnmounted(() => {
if (refreshTimer) {
clearInterval(refreshTimer);
refreshTimer = null;
clearInterval(refreshTimer)
refreshTimer = null
}
});
})
</script>
<template>
@@ -42,10 +45,21 @@ onUnmounted(() => {
</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>
@@ -54,7 +68,9 @@ onUnmounted(() => {
<span class="text-sm font-weight-medium">{{ item.name }}</span>
</VListItemTitle>
<VListItemSubtitle class="text-xs"> {{ item.next_run }}</VListItemSubtitle>
<VListItemSubtitle class="text-xs">
{{ item.next_run }}
</VListItemSubtitle>
<template #append>
<div>
@@ -65,7 +81,9 @@ onUnmounted(() => {
</template>
</VListItem>
<VListItem v-if="schedulerList.length === 0">
<VListItemTitle class="text-center">没有后台服务</VListItemTitle>
<VListItemTitle class="text-center">
没有后台服务
</VListItemTitle>
</VListItem>
</VList>
</VCardText>
+50 -33
View File
@@ -1,76 +1,83 @@
<script setup lang="ts">
import { formatFileSize } from "@/@core/utils/formatters";
import api from "@/api";
import { DownloaderInfo } from "@/api/types";
import { formatFileSize } from '@/@core/utils/formatters'
import api from '@/api'
import type { DownloaderInfo } from '@/api/types'
// 定时器
let refreshTimer: NodeJS.Timer | null = null;
let refreshTimer: NodeJS.Timer | null = null
// 下载器信息
const downloadInfo = ref<DownloaderInfo>({
// 下载速度
download_speed: 0,
// 上传速度
upload_speed: 0,
// 下载量
download_size: 0,
// 上传量
upload_size: 0,
// 剩余空间
free_space: 0,
});
})
// 显示项
const infoItems = ref([
{
avatar: "",
title: "",
amount: "",
avatar: '',
title: '',
amount: '',
},
]);
])
// 调用API查询下载器数据
const loadDownloaderInfo = async () => {
async function loadDownloaderInfo() {
try {
const res: DownloaderInfo = await api.get("dashboard/downloader");
downloadInfo.value = res;
const res: DownloaderInfo = await api.get('dashboard/downloader')
downloadInfo.value = res
infoItems.value = [
{
avatar: "mdi-cloud-upload",
title: "总上传量",
avatar: 'mdi-cloud-upload',
title: '总上传量',
amount: formatFileSize(res.upload_size),
},
{
avatar: "mdi-download-box",
title: "总下载量",
avatar: 'mdi-download-box',
title: '总下载量',
amount: formatFileSize(res.download_size),
},
{
avatar: "mdi-content-save",
title: "磁盘剩余空间",
avatar: 'mdi-content-save',
title: '磁盘剩余空间',
amount: formatFileSize(res.free_space),
},
];
} catch (e) {
console.log(e);
]
}
};
catch (e) {
console.log(e)
}
}
onMounted(() => {
loadDownloaderInfo();
loadDownloaderInfo()
// 启动定时器
refreshTimer = setInterval(() => {
loadDownloaderInfo();
}, 3000);
});
loadDownloaderInfo()
}, 3000)
})
// 组件卸载时停止定时器
onUnmounted(() => {
if (refreshTimer) {
clearInterval(refreshTimer);
refreshTimer = null;
clearInterval(refreshTimer)
refreshTimer = null
}
});
})
</script>
<template>
@@ -81,13 +88,23 @@ onUnmounted(() => {
<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">
+48 -27
View File
@@ -1,57 +1,78 @@
<script setup lang="ts">
import { formatFileSize } from "@/@core/utils/formatters";
import api from "@/api";
import trophy from "@images/misc/storage.png";
import triangleDark from "@images/misc/triangle-dark.png";
import triangleLight from "@images/misc/triangle-light.png";
import { useTheme } from "vuetify";
import { useTheme } from 'vuetify'
import { formatFileSize } from '@/@core/utils/formatters'
import api from '@/api'
import trophy from '@images/misc/storage.png'
import triangleDark from '@images/misc/triangle-dark.png'
import triangleLight from '@images/misc/triangle-light.png'
const { global } = useTheme()
const { global } = useTheme();
const triangleBg = computed(() =>
global.name.value === "light" ? triangleLight : triangleDark
);
global.name.value === 'light' ? triangleLight : triangleDark,
)
// 总存储空间
const storage = ref(0);
const storage = ref(0)
// 已使用存储空间
const used = ref(0);
const used = ref(0)
// 计算已使用存储空间百分比,精确到小数点后1位
const usedPercent = computed(() => {
return Math.round((used.value / storage.value) * 1000) / 10;
});
return Math.round((used.value / storage.value) * 1000) / 10
})
// 调用API,查询存储空间
const getStorage = async () => {
async function getStorage() {
try {
const res: Storage = await api.get("dashboard/storage");
storage.value = res.total_storage;
used.value = res.used_storage;
} catch (e) {
console.log(e);
const res: Storage = await api.get('dashboard/storage')
storage.value = res.total_storage
used.value = res.used_storage
}
};
catch (e) {
console.log(e)
}
}
onMounted(() => {
getStorage();
});
getStorage()
})
</script>
<template>
<VCard title="存储空间" subtitle="" class="position-relative">
<VCard
title="存储空间"
subtitle=""
class="position-relative"
>
<VCardText>
<h5 class="text-2xl font-weight-medium text-primary">
{{ formatFileSize(storage) }}
</h5>
<p class="mt-2">已使用 {{ usedPercent }}% 🚀</p>
<p class="mt-1"><VProgressLinear :model-value="usedPercent" color="primary" /></p>
<p class="mt-2">
已使用 {{ usedPercent }}% 🚀
</p>
<p class="mt-1">
<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>
+53 -38
View File
@@ -1,23 +1,24 @@
<script setup lang="ts">
import api from "@/api";
import { hexToRgb } from "@layouts/utils";
import VueApexCharts from "vue3-apexcharts";
import { useTheme } from "vuetify";
import VueApexCharts from 'vue3-apexcharts'
import { useTheme } from 'vuetify'
import api from '@/api'
import { hexToRgb } from '@layouts/utils'
const vuetifyTheme = useTheme();
const vuetifyTheme = useTheme()
const options = controlledComputed(
() => vuetifyTheme.name.value,
() => {
const currentTheme = ref(vuetifyTheme.current.value.colors);
const variableTheme = ref(vuetifyTheme.current.value.variables);
const currentTheme = ref(vuetifyTheme.current.value.colors)
const variableTheme = ref(vuetifyTheme.current.value.variables)
const disabledColor = `rgba(${hexToRgb(currentTheme.value["on-surface"])},${
variableTheme.value["disabled-opacity"]
})`;
const borderColor = `rgba(${hexToRgb(String(variableTheme.value["border-color"]))},${
variableTheme.value["border-opacity"]
})`;
const disabledColor = `rgba(${hexToRgb(currentTheme.value['on-surface'])},${
variableTheme.value['disabled-opacity']
})`
const borderColor = `rgba(${hexToRgb(String(variableTheme.value['border-color']))},${
variableTheme.value['border-opacity']
})`
return {
chart: {
@@ -28,9 +29,9 @@ const options = controlledComputed(
bar: {
borderRadius: 9,
distributed: true,
columnWidth: "40%",
endingShape: "rounded",
startingShape: "rounded",
columnWidth: '40%',
endingShape: 'rounded',
startingShape: 'rounded',
},
},
stroke: {
@@ -54,12 +55,12 @@ const options = controlledComputed(
dataLabels: { enabled: false },
colors: [currentTheme.value.primary],
states: {
hover: { filter: { type: "none" } },
active: { filter: { type: "none" } },
hover: { filter: { type: 'none' } },
active: { filter: { type: 'none' } },
},
xaxis: {
categories: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
tickPlacement: "on",
categories: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
tickPlacement: 'on',
labels: { show: false },
crosshairs: { opacity: 0 },
axisTicks: { show: false },
@@ -72,36 +73,38 @@ const options = controlledComputed(
offsetX: -17,
style: {
colors: disabledColor,
fontSize: "12px",
fontSize: '12px',
},
formatter: (value: number) =>
`${value > 999 ? `${(value / 1000).toFixed(0)}` : value}`,
value > 999 ? (value / 1000).toFixed(0) : value,
},
},
};
}
);
}
},
)
// 图表数据
const series = ref([{ data: [0, 0, 0, 0, 0, 0, 0] }]);
const series = ref([{ data: [0, 0, 0, 0, 0, 0, 0] }])
// 总数
const totalCount = computed(() => series.value[0].data.reduce((a, b) => a + b, 0));
const totalCount = computed(() => series.value[0].data.reduce((a, b) => a + b, 0))
// 调用API接口获取数据近7天数据
const getWeeklyData = async () => {
async function getWeeklyData() {
try {
const res: number[] = await api.get("dashboard/transfer");
series.value = [{ data: res }];
} catch (e) {
console.log(e);
const res: number[] = await api.get('dashboard/transfer')
series.value = [{ data: res }]
}
};
catch (e) {
console.log(e)
}
}
onMounted(() => {
getWeeklyData();
});
getWeeklyData()
})
</script>
<template>
@@ -111,14 +114,26 @@ onMounted(() => {
</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">{{ totalCount }}</h5>
<h5 class="text-h5 me-4">
{{ totalCount }}
</h5>
<p>最近一周入库了 {{ totalCount }} 部影片 😎</p>
</div>
<VBtn block to="/history"> 查看详情 </VBtn>
<VBtn
block
to="/history"
>
查看详情
</VBtn>
</VCardText>
</VCard>
</template>