mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 15:36:49 +08:00
Merge pull request #95 from dh336699/feature-issue-1851
This commit is contained in:
Vendored
+1
@@ -53,6 +53,7 @@
|
|||||||
"stylelint",
|
"stylelint",
|
||||||
"touchless",
|
"touchless",
|
||||||
"triggerer",
|
"triggerer",
|
||||||
|
"unref",
|
||||||
"vuetify"
|
"vuetify"
|
||||||
],
|
],
|
||||||
// Extension: Comment Anchors
|
// Extension: Comment Anchors
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"@casl/ability": "^6.2.0",
|
"@casl/ability": "^6.2.0",
|
||||||
"@casl/vue": "^2.2.0",
|
"@casl/vue": "^2.2.0",
|
||||||
"@floating-ui/dom": "1.6.3",
|
"@floating-ui/dom": "1.6.3",
|
||||||
|
"@iconify/utils": "^2.1.22",
|
||||||
"@vueuse/core": "^10.1.2",
|
"@vueuse/core": "^10.1.2",
|
||||||
"@vueuse/math": "^10.1.2",
|
"@vueuse/math": "^10.1.2",
|
||||||
"ace-builds": "^1.32.6",
|
"ace-builds": "^1.32.6",
|
||||||
@@ -89,6 +90,7 @@
|
|||||||
"eslint-plugin-sonarjs": "^0.25.1",
|
"eslint-plugin-sonarjs": "^0.25.1",
|
||||||
"eslint-plugin-unicorn": "^52.0.0",
|
"eslint-plugin-unicorn": "^52.0.0",
|
||||||
"eslint-plugin-vue": "^9.12.0",
|
"eslint-plugin-vue": "^9.12.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"postcss": "8",
|
"postcss": "8",
|
||||||
"postcss-html": "^1.5.0",
|
"postcss-html": "^1.5.0",
|
||||||
"stylelint": "16.3.1",
|
"stylelint": "16.3.1",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { debounce, cloneDeep } from 'lodash'
|
||||||
|
import { ref, unref } from 'vue'
|
||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { TransferHistory } from '@/api/types'
|
import type { TransferHistory } from '@/api/types'
|
||||||
@@ -58,11 +59,22 @@ const headers = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const pageRange = [
|
||||||
|
{title: '10', value: 10},
|
||||||
|
{title: '25', value: 25},
|
||||||
|
{title: '50', value: 50},
|
||||||
|
{title: '100', value: 100},
|
||||||
|
{title: 'All', value: -1}]
|
||||||
|
|
||||||
// 数据列表
|
// 数据列表
|
||||||
const dataList = ref<TransferHistory[]>([])
|
const dataList = ref<TransferHistory[]>([])
|
||||||
|
// 本地数据根据文件夹筛选
|
||||||
|
const backupList = ref<TransferHistory[]>([])
|
||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
const search = ref()
|
const search = ref()
|
||||||
|
//文件夹搜索
|
||||||
|
const searchFolder = ref()
|
||||||
|
|
||||||
// 搜索提示词列表
|
// 搜索提示词列表
|
||||||
const searchHintList = ref<string[]>([])
|
const searchHintList = ref<string[]>([])
|
||||||
@@ -94,8 +106,46 @@ const deleteConfirmDialog = ref(false)
|
|||||||
// 确认框标题
|
// 确认框标题
|
||||||
const confirmTitle = ref('')
|
const confirmTitle = ref('')
|
||||||
|
|
||||||
|
// 分页提示
|
||||||
|
const pageTip = computed(() => {
|
||||||
|
const begin = unref(itemsPerPage) * (unref(currentPage) - 1) + 1
|
||||||
|
const end = unref(itemsPerPage) * unref(currentPage) === -1 ? 'ALL' : unref(itemsPerPage) * unref(currentPage)
|
||||||
|
return {
|
||||||
|
begin,
|
||||||
|
end
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 分页总数
|
||||||
|
const totalPage = computed(() => {
|
||||||
|
const total = Math.ceil(unref(totalItems) /unref(itemsPerPage))
|
||||||
|
|
||||||
|
return total
|
||||||
|
})
|
||||||
|
|
||||||
|
// 切换页签
|
||||||
|
watch(
|
||||||
|
() => currentPage.value,
|
||||||
|
async () => {
|
||||||
|
await fetchData({ page: currentPage.value, itemsPerPage: itemsPerPage.value })
|
||||||
|
})
|
||||||
|
// 切换每页条数
|
||||||
|
watch(
|
||||||
|
() => itemsPerPage.value,
|
||||||
|
async () => {
|
||||||
|
await fetchData({ page: 1, itemsPerPage: itemsPerPage.value })
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSearchFolder = debounce(() => {
|
||||||
|
if (!unref(searchFolder)) {
|
||||||
|
dataList.value = unref(backupList)
|
||||||
|
} else {
|
||||||
|
dataList.value = unref(backupList).filter((data: any) => data!.src.includes(unref(searchFolder)) || data!.dest.includes(unref(searchFolder)))
|
||||||
|
}
|
||||||
|
}, 100)
|
||||||
|
|
||||||
// 获取订阅列表数据
|
// 获取订阅列表数据
|
||||||
async function fetchData({ page, itemsPerPage }: { page: number; itemsPerPage: number }) {
|
async function fetchData({ page, itemsPerPage }: { page: number; itemsPerPage: number }) {
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
currentPage.value = page
|
currentPage.value = page
|
||||||
@@ -109,6 +159,7 @@ async function fetchData({ page, itemsPerPage }: { page: number; itemsPerPage: n
|
|||||||
})
|
})
|
||||||
|
|
||||||
dataList.value = result.data.list
|
dataList.value = result.data.list
|
||||||
|
backupList.value = cloneDeep(unref(dataList))
|
||||||
totalItems.value = result.data.total
|
totalItems.value = result.data.total
|
||||||
searchHintList.value = ['失败', '成功', ...new Set(dataList.value.map(item => item.title || ''))].filter(
|
searchHintList.value = ['失败', '成功', ...new Set(dataList.value.map(item => item.title || ''))].filter(
|
||||||
title => title !== '',
|
title => title !== '',
|
||||||
@@ -318,7 +369,22 @@ fixArrayAt()
|
|||||||
<VCol cols="4" md="6">
|
<VCol cols="4" md="6">
|
||||||
历史记录
|
历史记录
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="8" md="6">
|
<VCol cols="8" md="6" class="flex">
|
||||||
|
<VCombobox
|
||||||
|
key="search_navbar"
|
||||||
|
v-model="searchFolder"
|
||||||
|
class="text-disabled mr-6"
|
||||||
|
density="compact"
|
||||||
|
label="选择目录"
|
||||||
|
append-inner-icon="mdi-magnify"
|
||||||
|
variant="solo-filled"
|
||||||
|
single-line
|
||||||
|
hide-details
|
||||||
|
flat
|
||||||
|
rounded
|
||||||
|
clearable
|
||||||
|
@update:search="handleSearchFolder"
|
||||||
|
/>
|
||||||
<VCombobox
|
<VCombobox
|
||||||
key="search_navbar"
|
key="search_navbar"
|
||||||
v-model="search"
|
v-model="search"
|
||||||
@@ -339,20 +405,99 @@ fixArrayAt()
|
|||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDataTableServer
|
<VDataTableServer
|
||||||
|
v-if="itemsPerPage !== -1"
|
||||||
v-model="selected"
|
v-model="selected"
|
||||||
v-model:items-per-page="itemsPerPage"
|
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:items="dataList"
|
:items="dataList"
|
||||||
:items-length="totalItems"
|
:items-length="totalItems"
|
||||||
:search="search"
|
:search="search"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
:item-value="'id' + Math.random()*1000"
|
||||||
|
return-object
|
||||||
|
fixed-header
|
||||||
|
show-select
|
||||||
|
loading-text="加载中..."
|
||||||
|
class="data-table-div"
|
||||||
|
:hide-default-footer="true"
|
||||||
|
:disable-pagination="true"
|
||||||
|
@update:options="fetchData"
|
||||||
|
>
|
||||||
|
<template #item.title="{ item }">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<VAvatar>
|
||||||
|
<VIcon :icon="getIcon(item.type || '')" />
|
||||||
|
</VAvatar>
|
||||||
|
<div class="d-flex flex-column ms-1">
|
||||||
|
<span class="d-block text-high-emphasis">
|
||||||
|
{{ item?.title }} {{ item?.seasons }}{{ item?.episodes }}
|
||||||
|
</span>
|
||||||
|
<small>{{ item?.category }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #item.src="{ item }">
|
||||||
|
<small>{{ item?.src }} <br>=> {{ item?.dest }}</small>
|
||||||
|
</template>
|
||||||
|
<template #item.mode="{ item }">
|
||||||
|
<VChip variant="outlined" color="primary" size="small">
|
||||||
|
{{ TransferDict[item?.mode || ''] }}
|
||||||
|
</VChip>
|
||||||
|
</template>
|
||||||
|
<template #item.status="{ item }">
|
||||||
|
<VChip v-if="item?.status" color="success" size="small">
|
||||||
|
成功
|
||||||
|
</VChip>
|
||||||
|
<v-tooltip v-else :text="item?.errmsg">
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<VChip v-bind="props" color="error" size="small">
|
||||||
|
失败
|
||||||
|
</VChip>
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
</template>
|
||||||
|
<template #item.date="{ item }">
|
||||||
|
<small>{{ item?.date }}</small>
|
||||||
|
</template>
|
||||||
|
<template #item.actions="{ item }">
|
||||||
|
<IconBtn>
|
||||||
|
<VIcon icon="mdi-dots-vertical" />
|
||||||
|
<VMenu activator="parent" close-on-content-click>
|
||||||
|
<VList>
|
||||||
|
<VListItem
|
||||||
|
v-for="(menu, i) in dropdownItems"
|
||||||
|
:key="i"
|
||||||
|
variant="plain"
|
||||||
|
:base-color="menu.props.color"
|
||||||
|
@click="menu.props.click(item)"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<VIcon :icon="menu.props.prependIcon" />
|
||||||
|
</template>
|
||||||
|
<VListItemTitle v-text="menu.title" />
|
||||||
|
</VListItem>
|
||||||
|
</VList>
|
||||||
|
</VMenu>
|
||||||
|
</IconBtn>
|
||||||
|
</template>
|
||||||
|
<template #no-data>
|
||||||
|
没有数据
|
||||||
|
</template>
|
||||||
|
<template v-slot:bottom>
|
||||||
|
<div/>
|
||||||
|
</template>
|
||||||
|
</VDataTableServer>
|
||||||
|
<VDataTableVirtual
|
||||||
|
v-else
|
||||||
|
v-model="selected"
|
||||||
|
v-model:items-per-page="itemsPerPage"
|
||||||
|
:headers="headers"
|
||||||
|
:items="dataList"
|
||||||
|
:search="search"
|
||||||
|
:loading="loading"
|
||||||
density="compact"
|
density="compact"
|
||||||
item-value="id"
|
|
||||||
return-object
|
return-object
|
||||||
fixed-header
|
fixed-header
|
||||||
show-select
|
show-select
|
||||||
items-per-page-text="每页条数"
|
|
||||||
page-text="{0}-{1} 共 {2} 条"
|
|
||||||
loading-text="加载中..."
|
loading-text="加载中..."
|
||||||
class="data-table-div"
|
class="data-table-div"
|
||||||
@update:options="fetchData"
|
@update:options="fetchData"
|
||||||
@@ -417,7 +562,25 @@ fixArrayAt()
|
|||||||
<template #no-data>
|
<template #no-data>
|
||||||
没有数据
|
没有数据
|
||||||
</template>
|
</template>
|
||||||
</VDataTableServer>
|
</VDataTableVirtual>
|
||||||
|
<div class="flex items-center justify-end">
|
||||||
|
<span class="page-text">每页条数</span>
|
||||||
|
<div class="!w-[90px] ml-[8px]">
|
||||||
|
<v-select
|
||||||
|
v-model="itemsPerPage"
|
||||||
|
:items="pageRange"
|
||||||
|
density="compact"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span class="page-text px-[16px]">{{pageTip.begin}}-{{pageTip.end}} 共 {{totalItems}} 条</span>
|
||||||
|
<v-pagination
|
||||||
|
v-model="currentPage"
|
||||||
|
show-first-last-page
|
||||||
|
:length="totalPage"
|
||||||
|
@next="currentPage + 1"
|
||||||
|
@prev="currentPage - 1"
|
||||||
|
></v-pagination>
|
||||||
|
</div>
|
||||||
</VCard>
|
</VCard>
|
||||||
<!-- 底部弹窗 -->
|
<!-- 底部弹窗 -->
|
||||||
<VBottomSheet v-model="deleteConfirmDialog" inset>
|
<VBottomSheet v-model="deleteConfirmDialog" inset>
|
||||||
@@ -496,6 +659,11 @@ fixArrayAt()
|
|||||||
}
|
}
|
||||||
|
|
||||||
.data-table-div {
|
.data-table-div {
|
||||||
block-size: calc(100vh - 12rem);
|
block-size: calc(100vh - 15.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-text {
|
||||||
|
color: rgba(58, 53, 65, 0.6);
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user