mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 08:46:40 +08:00
feat: 显示共享媒体识别统计
This commit is contained in:
@@ -1839,6 +1839,10 @@ export interface RecognitionCacheData {
|
|||||||
recognized: number
|
recognized: number
|
||||||
// 未识别数量
|
// 未识别数量
|
||||||
unrecognized: number
|
unrecognized: number
|
||||||
|
// 共享识别成功命中数量
|
||||||
|
shared_recognized: number
|
||||||
|
// 是否开启共享识别
|
||||||
|
shared_recognize_enabled: boolean
|
||||||
// 缓存数据
|
// 缓存数据
|
||||||
data: RecognitionCacheItem[]
|
data: RecognitionCacheItem[]
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-2
@@ -45,6 +45,8 @@ const cacheData = ref<RecognitionCacheData>({
|
|||||||
count: 0,
|
count: 0,
|
||||||
recognized: 0,
|
recognized: 0,
|
||||||
unrecognized: 0,
|
unrecognized: 0,
|
||||||
|
shared_recognized: 0,
|
||||||
|
shared_recognize_enabled: false,
|
||||||
data: [],
|
data: [],
|
||||||
})
|
})
|
||||||
const mobileVisibleCount = ref(MOBILE_CACHE_PAGE_SIZE)
|
const mobileVisibleCount = ref(MOBILE_CACHE_PAGE_SIZE)
|
||||||
@@ -111,9 +113,18 @@ async function loadCacheData(showSuccess = false) {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
const response = (await api.get(recognitionCacheEndpoint.value)) as unknown as ApiResponse<RecognitionCacheData>
|
const response = (await api.get(recognitionCacheEndpoint.value)) as unknown as ApiResponse<RecognitionCacheData>
|
||||||
if (requestId !== cacheLoadRequestId) return
|
if (requestId !== cacheLoadRequestId) return
|
||||||
const responseData = response.data ?? { count: 0, recognized: 0, unrecognized: 0, data: [] }
|
const responseData = response.data ?? {
|
||||||
|
count: 0,
|
||||||
|
recognized: 0,
|
||||||
|
unrecognized: 0,
|
||||||
|
shared_recognized: 0,
|
||||||
|
shared_recognize_enabled: false,
|
||||||
|
data: [],
|
||||||
|
}
|
||||||
cacheData.value = {
|
cacheData.value = {
|
||||||
...responseData,
|
...responseData,
|
||||||
|
shared_recognized: responseData.shared_recognized ?? 0,
|
||||||
|
shared_recognize_enabled: responseData.shared_recognize_enabled ?? false,
|
||||||
data: responseData.data.map(item => ({ ...item, recognition_id: getRecognitionId(item) })),
|
data: responseData.data.map(item => ({ ...item, recognition_id: getRecognitionId(item) })),
|
||||||
}
|
}
|
||||||
selectedItems.value = selectedItems.value.filter(key => cacheData.value.data.some(item => item.key === key))
|
selectedItems.value = selectedItems.value.filter(key => cacheData.value.data.some(item => item.key === key))
|
||||||
@@ -276,13 +287,20 @@ watch(recognitionSource, () => {
|
|||||||
<span>{{ t('setting.cache.recognized') }}</span>
|
<span>{{ t('setting.cache.recognized') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!isMobile" class="cache-panel-stat cache-panel-stat--warning">
|
<div v-if="!isMobile || cacheData.shared_recognize_enabled" class="cache-panel-stat cache-panel-stat--warning">
|
||||||
<VIcon icon="mdi-help-circle-outline" size="22" />
|
<VIcon icon="mdi-help-circle-outline" size="22" />
|
||||||
<div>
|
<div>
|
||||||
<strong>{{ cacheData.unrecognized }}</strong>
|
<strong>{{ cacheData.unrecognized }}</strong>
|
||||||
<span>{{ t('setting.cache.unrecognized') }}</span>
|
<span>{{ t('setting.cache.unrecognized') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="cacheData.shared_recognize_enabled" class="cache-panel-stat cache-panel-stat--info">
|
||||||
|
<VIcon icon="mdi-cloud-check-outline" :size="isMobile ? 32 : 22" />
|
||||||
|
<div>
|
||||||
|
<strong>{{ cacheData.shared_recognized }}</strong>
|
||||||
|
<span>{{ t('setting.cache.sharedRecognized') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!isMobile" class="cache-panel-actions">
|
<div v-if="!isMobile" class="cache-panel-actions">
|
||||||
@@ -550,6 +568,10 @@ watch(recognitionSource, () => {
|
|||||||
color: rgb(var(--v-theme-warning));
|
color: rgb(var(--v-theme-warning));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cache-panel-stat--info {
|
||||||
|
color: rgb(var(--v-theme-info));
|
||||||
|
}
|
||||||
|
|
||||||
.cache-panel-actions {
|
.cache-panel-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import RecognitionCachePanel from '@/components/cache/RecognitionCachePanel.vue'
|
||||||
|
import { screen, waitFor } from '@testing-library/vue'
|
||||||
|
import { renderWithProviders } from '@tests/support/render'
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
|
||||||
|
const mocks = vi.hoisted(() => ({
|
||||||
|
apiGet: vi.fn(),
|
||||||
|
toastError: vi.fn(),
|
||||||
|
toastSuccess: vi.fn(),
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/api', () => ({
|
||||||
|
default: {
|
||||||
|
get: mocks.apiGet,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('vue-toastification', () => ({
|
||||||
|
useToast: () => ({
|
||||||
|
error: mocks.toastError,
|
||||||
|
success: mocks.toastSuccess,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
|
async function renderRecognitionCachePanel() {
|
||||||
|
return renderWithProviders(RecognitionCachePanel, {
|
||||||
|
initialState: {
|
||||||
|
globalSettings: {
|
||||||
|
data: {
|
||||||
|
GLOBAL_IMAGE_CACHE: false,
|
||||||
|
RECOGNIZE_SOURCE: 'themoviedb',
|
||||||
|
TMDB_IMAGE_DOMAIN: 'image.tmdb.org',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('RecognitionCachePanel shared recognition statistics', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mocks.apiGet.mockReset()
|
||||||
|
mocks.toastError.mockReset()
|
||||||
|
mocks.toastSuccess.mockReset()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows the persisted shared recognition count when sharing is enabled', async () => {
|
||||||
|
mocks.apiGet.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
count: 12,
|
||||||
|
recognized: 9,
|
||||||
|
unrecognized: 3,
|
||||||
|
shared_recognized: 27,
|
||||||
|
shared_recognize_enabled: true,
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await renderRecognitionCachePanel()
|
||||||
|
|
||||||
|
expect(await screen.findByText('共享识别')).toBeInTheDocument()
|
||||||
|
expect(screen.getByText('27')).toBeInTheDocument()
|
||||||
|
expect(screen.getByText('未识别')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('hides shared recognition statistics when sharing is disabled', async () => {
|
||||||
|
mocks.apiGet.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
count: 12,
|
||||||
|
recognized: 9,
|
||||||
|
unrecognized: 3,
|
||||||
|
shared_recognized: 27,
|
||||||
|
shared_recognize_enabled: false,
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await renderRecognitionCachePanel()
|
||||||
|
await waitFor(() => expect(mocks.apiGet).toHaveBeenCalledWith('tmdb/cache'))
|
||||||
|
|
||||||
|
expect(screen.queryByText('共享识别')).not.toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -2536,6 +2536,7 @@ export default {
|
|||||||
totalCount: 'Total Count',
|
totalCount: 'Total Count',
|
||||||
siteCount: 'Site Count',
|
siteCount: 'Site Count',
|
||||||
recognized: 'Recognized',
|
recognized: 'Recognized',
|
||||||
|
sharedRecognized: 'Shared Recognition',
|
||||||
recognizedOnly: 'Recognized Only',
|
recognizedOnly: 'Recognized Only',
|
||||||
unrecognizedOnly: 'Unrecognized Only',
|
unrecognizedOnly: 'Unrecognized Only',
|
||||||
allStatuses: 'All Statuses',
|
allStatuses: 'All Statuses',
|
||||||
|
|||||||
@@ -2485,6 +2485,7 @@ export default {
|
|||||||
totalCount: '总条数',
|
totalCount: '总条数',
|
||||||
siteCount: '站点数',
|
siteCount: '站点数',
|
||||||
recognized: '已识别',
|
recognized: '已识别',
|
||||||
|
sharedRecognized: '共享识别',
|
||||||
recognizedOnly: '仅已识别',
|
recognizedOnly: '仅已识别',
|
||||||
unrecognizedOnly: '仅未识别',
|
unrecognizedOnly: '仅未识别',
|
||||||
allStatuses: '全部状态',
|
allStatuses: '全部状态',
|
||||||
|
|||||||
@@ -2484,6 +2484,7 @@ export default {
|
|||||||
totalCount: '總條數',
|
totalCount: '總條數',
|
||||||
siteCount: '站點數',
|
siteCount: '站點數',
|
||||||
recognized: '已識別',
|
recognized: '已識別',
|
||||||
|
sharedRecognized: '共享識別',
|
||||||
recognizedOnly: '僅已識別',
|
recognizedOnly: '僅已識別',
|
||||||
unrecognizedOnly: '僅未識別',
|
unrecognizedOnly: '僅未識別',
|
||||||
allStatuses: '全部狀態',
|
allStatuses: '全部狀態',
|
||||||
|
|||||||
Reference in New Issue
Block a user