From 8683b341e2918d129158292661dd567be979e0cb Mon Sep 17 00:00:00 2001 From: Script Generator Date: Tue, 30 Jun 2026 19:27:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=97=AE=E7=BF=BB=E5=B0=8F=E5=AE=9D):=20?= =?UTF-8?q?=E6=8E=A5=E5=85=A5=E9=9D=99=E6=80=81=E5=B8=AE=E5=8A=A9=E4=B8=AD?= =?UTF-8?q?=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/wenfan-xiaobao/page.tsx | 270 +++++++-- apps/web/lib/wenfan-help-articles.ts | 541 ++++++++++++++++++ apps/web/lib/wenfan-help-search.test.ts | 48 ++ apps/web/lib/wenfan-help-search.ts | 105 ++++ apps/web/lib/wenfan-xiaobao-ui.test.ts | 6 + .../help/wenfan-xiaobao/activity-logs.png | Bin 0 -> 217130 bytes .../help/wenfan-xiaobao/ai-decompose.png | Bin 0 -> 49886 bytes .../help/wenfan-xiaobao/bug-workflow.png | Bin 0 -> 49886 bytes .../help/wenfan-xiaobao/dev-task-workflow.png | Bin 0 -> 49886 bytes .../help/wenfan-xiaobao/product-create.png | Bin 0 -> 37154 bytes .../help/wenfan-xiaobao/product-plan.png | Bin 0 -> 49886 bytes .../help/wenfan-xiaobao/project-create.png | Bin 0 -> 44626 bytes .../help/wenfan-xiaobao/requirement-pool.png | Bin 0 -> 158000 bytes .../help/wenfan-xiaobao/research-plan.png | Bin 0 -> 49886 bytes .../wenfan-xiaobao/test-case-workflow.png | Bin 0 -> 49886 bytes .../help/wenfan-xiaobao/ui-design-plan.png | Bin 0 -> 49886 bytes .../help/wenfan-xiaobao/version-create.png | Bin 0 -> 49886 bytes .../version-requirement-include.png | Bin 0 -> 49886 bytes .../help/wenfan-xiaobao/xiaobao-warning.png | Bin 0 -> 149235 bytes .../capture-wenfan-help-screenshots.mjs | 270 +++++++++ .../2026-06-30-wenfan-xiaobao-help-center.md | 229 ++++++++ 21 files changed, 1422 insertions(+), 47 deletions(-) create mode 100644 apps/web/lib/wenfan-help-articles.ts create mode 100644 apps/web/lib/wenfan-help-search.test.ts create mode 100644 apps/web/lib/wenfan-help-search.ts create mode 100644 apps/web/public/help/wenfan-xiaobao/activity-logs.png create mode 100644 apps/web/public/help/wenfan-xiaobao/ai-decompose.png create mode 100644 apps/web/public/help/wenfan-xiaobao/bug-workflow.png create mode 100644 apps/web/public/help/wenfan-xiaobao/dev-task-workflow.png create mode 100644 apps/web/public/help/wenfan-xiaobao/product-create.png create mode 100644 apps/web/public/help/wenfan-xiaobao/product-plan.png create mode 100644 apps/web/public/help/wenfan-xiaobao/project-create.png create mode 100644 apps/web/public/help/wenfan-xiaobao/requirement-pool.png create mode 100644 apps/web/public/help/wenfan-xiaobao/research-plan.png create mode 100644 apps/web/public/help/wenfan-xiaobao/test-case-workflow.png create mode 100644 apps/web/public/help/wenfan-xiaobao/ui-design-plan.png create mode 100644 apps/web/public/help/wenfan-xiaobao/version-create.png create mode 100644 apps/web/public/help/wenfan-xiaobao/version-requirement-include.png create mode 100644 apps/web/public/help/wenfan-xiaobao/xiaobao-warning.png create mode 100644 apps/web/scripts/capture-wenfan-help-screenshots.mjs create mode 100644 docs/superpowers/plans/2026-06-30-wenfan-xiaobao-help-center.md diff --git a/apps/web/app/wenfan-xiaobao/page.tsx b/apps/web/app/wenfan-xiaobao/page.tsx index 70ff52a..04d2366 100644 --- a/apps/web/app/wenfan-xiaobao/page.tsx +++ b/apps/web/app/wenfan-xiaobao/page.tsx @@ -1,48 +1,116 @@ 'use client'; +import { FormEvent, KeyboardEvent, useMemo, useState } from 'react'; import { BotMessageSquare, + Image as ImageIcon, MessageCircleQuestionMark, Mic, - Plus, Search, SendHorizontal, + Sparkles, SquarePen, } from 'lucide-react'; +import { WENFAN_HELP_ARTICLES, type HelpArticle } from '@/lib/wenfan-help-articles'; +import { getFallbackHelpSuggestions, searchHelpArticles, type HelpSearchResult } from '@/lib/wenfan-help-search'; -const HISTORY_ITEMS = [ - { title: '如何从产品创建到版本发布?', time: '今天' }, - { title: '需求池的状态分别代表什么?', time: '今天' }, - { title: '成员离职后怎么转交任务?', time: '昨天' }, - { title: 'AI 配置和模型在哪里维护?', time: '昨天' }, - { title: '测试用例失败后怎么提 Bug?', time: '周一' }, -]; +type ChatMessage = + | { + id: string; + role: 'assistant'; + type: 'intro'; + content: string; + } + | { + id: string; + role: 'user'; + type: 'text'; + content: string; + } + | { + id: string; + role: 'assistant'; + type: 'article'; + result: HelpSearchResult; + } + | { + id: string; + role: 'assistant'; + type: 'fallback'; + content: string; + suggestions: string[]; + }; -const QUICK_QUESTIONS = [ - '怎么创建一个版本?', - '怎么把需求关联到项目?', - '小宝预警的红点是什么意思?', -]; - -const MESSAGES = [ +const INITIAL_MESSAGES: ChatMessage[] = [ { + id: 'intro', role: 'assistant', - title: '问翻小宝', - content: '我是 FTB 的系统帮助助手。你可以直接问产品、项目、版本、需求、任务、测试、Bug、权限和 AI 配置相关的使用问题。', - }, - { - role: 'user', - title: '我', - content: '怎么把需求放进某个版本里?', - }, - { - role: 'assistant', - title: '问翻小宝', - content: '进入版本详情后,在需求区域选择当前项目下已采纳的需求;保存后,版本会基于这些需求继续承载开发任务、测试用例和发布风险分析。', + type: 'intro', + content: + '我是问翻小宝,第一阶段只从内置帮助中心回答系统怎么用,不调用 AI,也不消耗模型 token。你可以问产品、项目、版本、需求池、开发任务、测试用例、Bug 和日志记录。', }, ]; +const STARTER_QUESTIONS = getFallbackHelpSuggestions(); + export default function WenfanXiaobaoPage() { + const [messages, setMessages] = useState(INITIAL_MESSAGES); + const [input, setInput] = useState(''); + const [history, setHistory] = useState([ + '怎么新建产品?', + '怎么把需求纳入版本?', + '开发任务怎么提测?', + '测试用例失败后怎么提 Bug?', + '日志记录会记录哪些行为?', + ]); + + const visibleHistory = useMemo(() => history.slice(0, 12), [history]); + + function askQuestion(rawQuestion: string) { + const question = rawQuestion.trim(); + if (!question) return; + + const results = searchHelpArticles(question, WENFAN_HELP_ARTICLES); + const userMessage: ChatMessage = { + id: `user-${Date.now()}`, + role: 'user', + type: 'text', + content: question, + }; + + const assistantMessage: ChatMessage = + results.length > 0 + ? { + id: `article-${Date.now()}`, + role: 'assistant', + type: 'article', + result: results[0], + } + : { + id: `fallback-${Date.now()}`, + role: 'assistant', + type: 'fallback', + content: '暂时没有找到对应的内置帮助内容。你可以换个关键词,或者从下面这些常见问题开始。', + suggestions: STARTER_QUESTIONS, + }; + + setMessages((current) => [...current, userMessage, assistantMessage]); + setHistory((current) => [question, ...current.filter((item) => item !== question)]); + setInput(''); + } + + function handleSubmit(event: FormEvent) { + event.preventDefault(); + askQuestion(input); + } + + function handleTextareaKeyDown(event: KeyboardEvent) { + if (event.key === 'Enter' && !event.shiftKey) { + event.preventDefault(); + askQuestion(input); + } + } + return (
@@ -50,6 +118,10 @@ export default function WenfanXiaobaoPage() {
))}
@@ -95,20 +168,21 @@ export default function WenfanXiaobaoPage() {

问翻小宝

- 对话 + 内置帮助
- {MESSAGES.map((message) => ( - + {messages.map((message) => ( + ))}
- {QUICK_QUESTIONS.map((question) => ( + {STARTER_QUESTIONS.map((question) => (