diff --git a/frontend-web/src/core/recommended-questions/index.ts b/frontend-web/src/core/recommended-questions/index.ts index a7a5b286..40c36723 100644 --- a/frontend-web/src/core/recommended-questions/index.ts +++ b/frontend-web/src/core/recommended-questions/index.ts @@ -1,8 +1,12 @@ +import type { Tag } from "@/core/tags"; + export interface RecommendedQuestion { id: string; title: string; content: string; sort_order: number; + /** Tags assigned to this question (按岗位分发标签). */ + tags?: Tag[]; created_at?: string; updated_at?: string; } diff --git a/frontend-web/src/core/tags/hooks.ts b/frontend-web/src/core/tags/hooks.ts index 42861feb..950eb082 100644 --- a/frontend-web/src/core/tags/hooks.ts +++ b/frontend-web/src/core/tags/hooks.ts @@ -83,6 +83,7 @@ export function useSetResourceTags() { void queryClient.invalidateQueries({ queryKey: ["skills"] }); void queryClient.invalidateQueries({ queryKey: ["agents"] }); void queryClient.invalidateQueries({ queryKey: ["scheduled-tasks"] }); + void queryClient.invalidateQueries({ queryKey: ["recommended-questions"] }); }, }); } diff --git a/frontend-web/src/pages/RecommendedQuestionsPage.tsx b/frontend-web/src/pages/RecommendedQuestionsPage.tsx index 7fa85e0d..c8d76bdf 100644 --- a/frontend-web/src/pages/RecommendedQuestionsPage.tsx +++ b/frontend-web/src/pages/RecommendedQuestionsPage.tsx @@ -15,6 +15,8 @@ import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { ResourceTagDialog } from "@/components/workspace/tags/resource-tag-dialog"; +import { TagChipList } from "@/components/workspace/tags/tag-chip"; +import { TagSearchBar } from "@/components/workspace/tags/tag-search-bar"; import { useTheme } from "@/contexts/ThemeContext"; import { Dialog, @@ -83,6 +85,25 @@ export default function RecommendedQuestionsPage({ const [dragIndex, setDragIndex] = useState(null); const [dragOverIndex, setDragOverIndex] = useState(null); + // 名称 / 标签搜索 + const [search, setSearch] = useState(""); + const [tagIds, setTagIds] = useState([]); + + const isFiltering = search.trim() !== "" || tagIds.length > 0; + const needle = search.trim().toLowerCase(); + const visibleQuestions = isFiltering + ? questions.filter((q) => { + const matchesText = + needle === "" || + q.title.toLowerCase().includes(needle) || + q.content.toLowerCase().includes(needle); + const matchesTags = + tagIds.length === 0 || + (q.tags ?? []).some((t) => tagIds.includes(t.id)); + return matchesText && matchesTags; + }) + : questions; + function openAdd() { setFormTitle(""); setFormContent(""); @@ -203,6 +224,16 @@ export default function RecommendedQuestionsPage({ + {!isLoading && !error && questions.length > 0 && ( + + )} + {isLoading ? (
@@ -219,15 +250,19 @@ export default function RecommendedQuestionsPage({ 添加第一个问题
+ ) : visibleQuestions.length === 0 ? ( +
+

没有匹配的推荐问题

+
) : (
- {questions.map((q, index) => ( + {visibleQuestions.map((q, index) => (
handleDragStart(index)} - onDragOver={(e) => handleDragOver(e, index)} - onDrop={() => handleDrop(index)} + draggable={!isFiltering} + onDragStart={() => !isFiltering && handleDragStart(index)} + onDragOver={(e) => !isFiltering && handleDragOver(e, index)} + onDrop={() => !isFiltering && handleDrop(index)} onDragEnd={() => { setDragIndex(null); setDragOverIndex(null); @@ -238,7 +273,13 @@ export default function RecommendedQuestionsPage({ : "border-[#e4e4e7]" }`} > - +
{q.title} @@ -246,6 +287,9 @@ export default function RecommendedQuestionsPage({
{q.content}
+ {(q.tags?.length ?? 0) > 0 && ( + + )}