mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-08 01:06:41 +08:00
refactor(cache): manage TMDB recognition cache only
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "moviepilot",
|
||||
"version": "2.15.4",
|
||||
"version": "2.15.5",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"bin": "dist/service.js",
|
||||
|
||||
+1
-3
@@ -1889,9 +1889,7 @@ export interface RecognitionCacheItem {
|
||||
key: string
|
||||
// TMDB ID,0 表示未识别
|
||||
tmdb_id?: number
|
||||
// 豆瓣 ID,0 表示未识别
|
||||
douban_id?: string | number
|
||||
// 当前识别数据源对应的统一 ID
|
||||
// 识别缓存对应的字符串 ID
|
||||
recognition_id?: string
|
||||
// 识别后的标题
|
||||
title: string
|
||||
|
||||
+11
-29
@@ -11,9 +11,9 @@ import { getDisplayImageUrl } from '@/utils/imageUtils'
|
||||
|
||||
type RecognitionStatusFilter = 'all' | 'recognized' | 'unrecognized'
|
||||
type InfiniteScrollStatus = 'ok' | 'empty' | 'loading' | 'error'
|
||||
type RecognitionCacheSource = 'tmdb' | 'douban'
|
||||
|
||||
const MOBILE_CACHE_PAGE_SIZE = 20
|
||||
const RECOGNITION_CACHE_ENDPOINT = 'tmdb/cache'
|
||||
|
||||
const { t } = useI18n()
|
||||
const display = useDisplay()
|
||||
@@ -22,18 +22,8 @@ const $toast = useToast()
|
||||
const globalSettingsStore = useGlobalSettingsStore()
|
||||
|
||||
const isMobile = computed(() => display.smAndDown.value)
|
||||
const recognitionSource = computed<RecognitionCacheSource>(() =>
|
||||
globalSettingsStore.globalSettings.RECOGNIZE_SOURCE === 'douban' ? 'douban' : 'tmdb',
|
||||
)
|
||||
const recognitionSourceName = computed(() =>
|
||||
recognitionSource.value === 'douban'
|
||||
? t('setting.cache.recognitionSource.douban')
|
||||
: t('setting.cache.recognitionSource.themoviedb'),
|
||||
)
|
||||
const recognitionIdLabel = computed(() =>
|
||||
recognitionSource.value === 'douban' ? t('setting.cache.doubanId') : t('setting.cache.tmdbId'),
|
||||
)
|
||||
const recognitionCacheEndpoint = computed(() => `${recognitionSource.value}/cache`)
|
||||
const recognitionSourceName = computed(() => t('setting.cache.recognitionSource.themoviedb'))
|
||||
const recognitionIdLabel = computed(() => t('setting.cache.tmdbId'))
|
||||
const recognitionFilterPlaceholder = computed(() =>
|
||||
t('setting.cache.filterRecognitionCache', { source: recognitionSourceName.value }),
|
||||
)
|
||||
@@ -106,12 +96,12 @@ function loadMoreMobileCache({ done }: { done: (status: InfiniteScrollStatus) =>
|
||||
done(mobileHasMore.value ? 'ok' : 'empty')
|
||||
}
|
||||
|
||||
/** 加载当前识别数据源对应的缓存列表。 */
|
||||
/** 加载 TMDB 主识别缓存列表。 */
|
||||
async function loadCacheData(showSuccess = false) {
|
||||
const requestId = ++cacheLoadRequestId
|
||||
try {
|
||||
loading.value = true
|
||||
const response = (await api.get(recognitionCacheEndpoint.value)) as unknown as ApiResponse<RecognitionCacheData>
|
||||
const response = (await api.get(RECOGNITION_CACHE_ENDPOINT)) as unknown as ApiResponse<RecognitionCacheData>
|
||||
if (requestId !== cacheLoadRequestId) return
|
||||
const responseData = response.data ?? {
|
||||
count: 0,
|
||||
@@ -139,7 +129,7 @@ async function loadCacheData(showSuccess = false) {
|
||||
}
|
||||
}
|
||||
|
||||
/** 清空当前识别数据源的全部识别缓存。 */
|
||||
/** 清空全部 TMDB 主识别缓存。 */
|
||||
async function clearAllCache() {
|
||||
const confirmed = await createConfirm({
|
||||
type: 'warn',
|
||||
@@ -150,7 +140,7 @@ async function clearAllCache() {
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
const response = (await api.delete(recognitionCacheEndpoint.value)) as unknown as ApiResponse
|
||||
const response = (await api.delete(RECOGNITION_CACHE_ENDPOINT)) as unknown as ApiResponse
|
||||
if (!response.success) throw new Error(response.message)
|
||||
$toast.success(response.message || t('setting.cache.clearSuccess'))
|
||||
await loadCacheData()
|
||||
@@ -163,10 +153,10 @@ async function clearAllCache() {
|
||||
}
|
||||
}
|
||||
|
||||
/** 请求当前识别数据源接口删除指定识别缓存。 */
|
||||
/** 请求 TMDB 接口删除指定识别缓存。 */
|
||||
async function deleteCacheItem(key: string) {
|
||||
const response = (await api.delete(
|
||||
`${recognitionCacheEndpoint.value}/${encodeURIComponent(key)}`,
|
||||
`${RECOGNITION_CACHE_ENDPOINT}/${encodeURIComponent(key)}`,
|
||||
)) as unknown as ApiResponse
|
||||
if (!response.success) throw new Error(response.message)
|
||||
}
|
||||
@@ -217,10 +207,9 @@ function getPosterUrl(item: RecognitionCacheItem): string {
|
||||
return getDisplayImageUrl(sourceUrl, globalSettingsStore.globalSettings.GLOBAL_IMAGE_CACHE)
|
||||
}
|
||||
|
||||
/** 获取当前识别数据源对应的媒体 ID。 */
|
||||
/** 获取识别缓存对应的 TMDB ID。 */
|
||||
function getRecognitionId(item: RecognitionCacheItem): string {
|
||||
const recognitionId = recognitionSource.value === 'douban' ? item.douban_id : item.tmdb_id
|
||||
return recognitionId ? String(recognitionId) : ''
|
||||
return item.tmdb_id ? String(item.tmdb_id) : ''
|
||||
}
|
||||
|
||||
/** 判断识别缓存条目是否包含有效媒体 ID。 */
|
||||
@@ -260,13 +249,6 @@ onMounted(() => {
|
||||
watch([searchFilter, statusFilter], () => {
|
||||
resetMobilePagination()
|
||||
})
|
||||
|
||||
watch(recognitionSource, () => {
|
||||
searchFilter.value = ''
|
||||
statusFilter.value = 'all'
|
||||
selectedItems.value = []
|
||||
void loadCacheData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -22,13 +22,13 @@ vi.mock('vue-toastification', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
async function renderRecognitionCachePanel() {
|
||||
async function renderRecognitionCachePanel(recognitionSource = 'themoviedb') {
|
||||
return renderWithProviders(RecognitionCachePanel, {
|
||||
initialState: {
|
||||
globalSettings: {
|
||||
data: {
|
||||
GLOBAL_IMAGE_CACHE: false,
|
||||
RECOGNIZE_SOURCE: 'themoviedb',
|
||||
RECOGNIZE_SOURCE: recognitionSource,
|
||||
TMDB_IMAGE_DOMAIN: 'image.tmdb.org',
|
||||
},
|
||||
},
|
||||
@@ -79,4 +79,21 @@ describe('RecognitionCachePanel shared recognition statistics', () => {
|
||||
|
||||
expect(screen.queryByText('共享识别')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('loads TMDB cache even when Douban is selected as the recognition source', async () => {
|
||||
mocks.apiGet.mockResolvedValue({
|
||||
data: {
|
||||
count: 0,
|
||||
recognized: 0,
|
||||
unrecognized: 0,
|
||||
shared_recognized: 0,
|
||||
shared_recognize_enabled: false,
|
||||
data: [],
|
||||
},
|
||||
})
|
||||
|
||||
await renderRecognitionCachePanel('douban')
|
||||
|
||||
await waitFor(() => expect(mocks.apiGet).toHaveBeenCalledWith('tmdb/cache'))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2033,8 +2033,8 @@ export default {
|
||||
tmdbLocale: 'TMDB Metadata Language',
|
||||
tmdbLocalePlaceholder: 'en',
|
||||
tmdbLocaleHint: 'Customize TheMovieDb metadata language',
|
||||
metaCacheExpire: 'Media Metadata Cache Expiration Time',
|
||||
metaCacheExpireHint: 'Recognition metadata local cache time, use built-in default value when set to 0',
|
||||
metaCacheExpire: 'Per-item Media Metadata Cache TTL',
|
||||
metaCacheExpireHint: 'Independent TTL for each recognition metadata item; use the built-in default when set to 0',
|
||||
metaCacheExpireRequired: 'Please enter metadata cache time',
|
||||
metaCacheExpireMin: 'Metadata cache time must be greater than or equal to 0',
|
||||
scrapFollowTmdb: 'Follow TMDB Recognition',
|
||||
|
||||
@@ -2008,8 +2008,8 @@ export default {
|
||||
tmdbLocale: 'TMDB 元数据语言',
|
||||
tmdbLocalePlaceholder: 'zh',
|
||||
tmdbLocaleHint: '自定义 TheMovieDb 元数据语言',
|
||||
metaCacheExpire: '媒体元数据缓存过期时间',
|
||||
metaCacheExpireHint: '识别元数据本地缓存时间,为 0 时使用内置默认值',
|
||||
metaCacheExpire: '单条媒体元数据缓存有效期',
|
||||
metaCacheExpireHint: '每条识别元数据的独立有效期,为 0 时使用内置默认值',
|
||||
metaCacheExpireRequired: '请输入元数据缓存时间',
|
||||
metaCacheExpireMin: '元数据缓存时间必须大于等于0',
|
||||
scrapFollowTmdb: '跟随TMDB识别整理',
|
||||
|
||||
@@ -2007,8 +2007,8 @@ export default {
|
||||
tmdbLocale: 'TMDB 元數據語言',
|
||||
tmdbLocalePlaceholder: 'zh',
|
||||
tmdbLocaleHint: '自定義 TheMovieDb 元數據語言',
|
||||
metaCacheExpire: '媒體元數據緩存過期時間',
|
||||
metaCacheExpireHint: '識別元數據本地緩存時間,為 0 時使用內置默認值',
|
||||
metaCacheExpire: '單筆媒體元數據緩存有效期',
|
||||
metaCacheExpireHint: '每筆識別元數據的獨立有效期,為 0 時使用內置默認值',
|
||||
metaCacheExpireRequired: '請輸入元數據緩存時間',
|
||||
metaCacheExpireMin: '元數據緩存時間必須大於等於0',
|
||||
scrapFollowTmdb: '跟隨TMDB識別整理',
|
||||
|
||||
Reference in New Issue
Block a user