Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

Commit 465afb3

Browse files
committed
feat: extend ArticleSelectorModal to include Page type
- Added support for selecting 'Page' articles in the ArticleSelectorModal component. - Updated the filtering options and API calls to fetch pages alongside posts and notes, enhancing the article selection functionality. - Introduced new icons and labels for the Page type to improve user interface clarity. These changes aim to provide users with a more comprehensive selection of articles, including pages, for AI translation tasks. Signed-off-by: Innei <tukon479@gmail.com>
1 parent 7ee4ca0 commit 465afb3

1 file changed

Lines changed: 54 additions & 15 deletions

File tree

src/views/ai/components/article-selector-modal.tsx

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* 文章选择器弹窗 - 用于批量生成 AI 翻译
44
*/
55
import {
6+
File as FileIcon,
67
FileText as FileTextIcon,
78
Languages as LanguagesIcon,
89
Search as SearchIcon,
@@ -26,11 +27,12 @@ import { debouncedRef } from '@vueuse/core'
2627

2728
import { aiApi, AITaskType } from '~/api/ai'
2829
import { notesApi } from '~/api/notes'
30+
import { pagesApi } from '~/api/pages'
2931
import { postsApi } from '~/api/posts'
3032
import { searchApi } from '~/api/search'
3133
import { useAiTaskQueue } from '~/components/ai-task-queue'
3234

33-
type ArticleRefType = 'Post' | 'Note'
35+
type ArticleRefType = 'Post' | 'Note' | 'Page'
3436

3537
interface SelectableArticle {
3638
id: string
@@ -42,17 +44,20 @@ interface SelectableArticle {
4244
const RefTypeLabels: Record<ArticleRefType, string> = {
4345
Post: '文章',
4446
Note: '手记',
47+
Page: '页面',
4548
}
4649

4750
const RefTypeIcons: Record<ArticleRefType, typeof FileTextIcon> = {
4851
Post: FileTextIcon,
4952
Note: StickyNoteIcon,
53+
Page: FileIcon,
5054
}
5155

5256
const typeFilterOptions = [
5357
{ label: '全部类型', value: 'all' },
5458
{ label: '文章', value: 'Post' },
5559
{ label: '手记', value: 'Note' },
60+
{ label: '页面', value: 'Page' },
5661
]
5762

5863
export const ArticleSelectorModal = defineComponent({
@@ -88,19 +93,25 @@ export const ArticleSelectorModal = defineComponent({
8893
try {
8994
const allArticles: SelectableArticle[] = []
9095

91-
if (keyword && keyword.trim()) {
92-
const shouldSearchPosts =
93-
typeFilter.value === 'all' || typeFilter.value === 'Post'
94-
const shouldSearchNotes =
95-
typeFilter.value === 'all' || typeFilter.value === 'Note'
96+
const shouldFetchPosts =
97+
typeFilter.value === 'all' || typeFilter.value === 'Post'
98+
const shouldFetchNotes =
99+
typeFilter.value === 'all' || typeFilter.value === 'Note'
100+
const shouldFetchPages =
101+
typeFilter.value === 'all' || typeFilter.value === 'Page'
96102

97-
const [postsRes, notesRes] = await Promise.all([
98-
shouldSearchPosts
103+
if (keyword && keyword.trim()) {
104+
const [postsRes, notesRes, pagesRes] = await Promise.all([
105+
shouldFetchPosts
99106
? searchApi.searchPosts({ keyword, size: 50 })
100107
: Promise.resolve({ data: [] }),
101-
shouldSearchNotes
108+
shouldFetchNotes
102109
? searchApi.searchNotes({ keyword, size: 50 })
103110
: Promise.resolve({ data: [] }),
111+
// Pages 没有搜索 API,获取全部后前端过滤
112+
shouldFetchPages
113+
? pagesApi.getList({ select: 'title' })
114+
: Promise.resolve({ data: [] }),
104115
])
105116

106117
const posts = Array.isArray(postsRes)
@@ -126,19 +137,35 @@ export const ArticleSelectorModal = defineComponent({
126137
selected: selectedIds.value.has(note.id),
127138
})
128139
})
129-
} else {
130-
const shouldFetchPosts =
131-
typeFilter.value === 'all' || typeFilter.value === 'Post'
132-
const shouldFetchNotes =
133-
typeFilter.value === 'all' || typeFilter.value === 'Note'
134140

135-
const [postsRes, notesRes] = await Promise.all([
141+
// Pages 前端过滤
142+
const pages = Array.isArray(pagesRes)
143+
? pagesRes
144+
: (pagesRes?.data ?? [])
145+
const lowerKeyword = keyword.toLowerCase()
146+
pages
147+
.filter((page: { title: string }) =>
148+
page.title.toLowerCase().includes(lowerKeyword),
149+
)
150+
.forEach((page: { id: string; title: string }) => {
151+
allArticles.push({
152+
id: page.id,
153+
title: page.title,
154+
type: 'Page',
155+
selected: selectedIds.value.has(page.id),
156+
})
157+
})
158+
} else {
159+
const [postsRes, notesRes, pagesRes] = await Promise.all([
136160
shouldFetchPosts
137161
? postsApi.getList({ size: 50, select: 'title' })
138162
: Promise.resolve({ data: [] }),
139163
shouldFetchNotes
140164
? notesApi.getList({ size: 50, select: 'title' })
141165
: Promise.resolve({ data: [] }),
166+
shouldFetchPages
167+
? pagesApi.getList({ select: 'title' })
168+
: Promise.resolve({ data: [] }),
142169
])
143170

144171
const posts = Array.isArray(postsRes)
@@ -164,6 +191,18 @@ export const ArticleSelectorModal = defineComponent({
164191
selected: selectedIds.value.has(note.id),
165192
})
166193
})
194+
195+
const pages = Array.isArray(pagesRes)
196+
? pagesRes
197+
: (pagesRes?.data ?? [])
198+
pages.forEach((page: { id: string; title: string }) => {
199+
allArticles.push({
200+
id: page.id,
201+
title: page.title,
202+
type: 'Page',
203+
selected: selectedIds.value.has(page.id),
204+
})
205+
})
167206
}
168207

169208
articles.value = allArticles

0 commit comments

Comments
 (0)