8f7f082c3d
- 重构项目目录结构,将功能模块移至 modules/ 目录 - 创建平台同步基础架构,包括发布器基类和 GitHub 发布器 - 新增 UI 状态管理模块 (modules/ui/state.py) 统一管理会话状态 - 更新依赖配置,添加平台同步所需依赖 (httpx, pyperclip) - 整理文档结构,将所有文档分类移至 docs/ 目录 - 添加 .cursorrules 文件定义项目开发规范 - 清理根目录重复文件,保持项目结构整洁
40 KiB
40 KiB
Tab 1:关键词蒸馏 - 优化分析报告
分析维度:逻辑 / UI 布局 / 用户体验
分析日期:2026-01-28
分析范围:Tab 1 完整功能模块
📋 目录
全局问题:序号使用规范
判断标准:何时保留、何时删除序号
✅ 保留序号的情况
-
流程型 Tab(有明确顺序依赖)
- 示例:Tab 1 → Tab 2 → Tab 3(关键词 → 创作 → 优化)
- 理由:序号帮助用户理解工作流顺序
-
教程/引导型内容
- 示例:"步骤 1:配置 → 步骤 2:生成 → 步骤 3:验证"
- 理由:序号是内容的一部分,不可省略
-
Tab 数量 > 5 个
- 理由:序号帮助快速定位("第 7 个 Tab")
❌ 删除序号的情况
-
功能型 Tab(无顺序依赖)
- 当前情况:Tab 1-10 虽然有一定流程,但用户可能跳转使用
- 理由:序号造成视觉噪音,Tab 名称本身已足够清晰
-
Tab 数量 ≤ 5 个
- 理由:无需序号即可快速识别
-
Tab 内模块标题
- 当前问题:Tab 1 内无序号,但其他 Tab 可能有
- 理由:通过视觉层级(h2/h3/emoji)已能区分
推荐方案:默认去掉 Tab 名称中的序号
理由:
- Tab 名称已足够描述性("关键词蒸馏" vs "1 关键词蒸馏")
- 减少视觉噪音,提升现代感
- 用户通过 Tab 位置和名称即可识别,无需序号
替代方案:
- 使用 emoji 图标 增强识别度(已部分实现)
- 使用 视觉分组(通过间距、分隔线)
- 使用 颜色/高亮 区分重要 Tab
如何通过标题层级/分组/间距替代"序号引导"
方案 A:视觉层级(推荐)
# Tab 名称(无序号)
st.tabs([
"🎯 关键词蒸馏", # 核心功能,emoji 突出
"✍️ 自动创作", # 核心功能
"🔧 文章优化", # 核心功能
"✅ 多模型验证", # 验证功能
"📊 AI 数据报表", # 分析功能
# ...
])
方案 B:分组 + 分隔符
# 主要流程组
st.tabs([
"关键词蒸馏",
"自动创作",
"文章优化",
"多模型验证",
"---", # 分隔符(视觉分组)
"历史记录",
"AI 数据报表",
# ...
])
方案 C:保留序号但优化样式
# 序号作为副标题(更轻量)
st.tabs([
"关键词蒸馏 · 1",
"自动创作 · 2",
# ...
])
最终推荐:方案 A(去掉序号,保留 emoji,通过视觉层级区分)
Tab 1 重排后的结构草图
当前结构问题
- 信息分散:功能模块之间缺乏明确分组
- 条件显示混乱:部分功能仅在有关键词时显示,但布局不清晰
- 重复输入:品牌/优势信息在侧边栏,但某些功能可能需要重复输入
- 视觉层级不清晰:所有模块使用相同的
st.markdown("#### ...")层级
重排后的布局结构
┌─────────────────────────────────────────────────────────┐
│ Tab 1: 关键词蒸馏 │
├─────────────────────────────────────────────────────────┤
│ │
│ 【区域 1:模式选择】(始终显示,顶部固定) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 生成模式: [AI生成] [托词工具] [混合模式] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 【区域 2:配置区】(条件显示:托词工具/混合模式) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 📐 组合模式选择 │ │
│ │ - 多选组合模式 │ │
│ │ - [展开:组合模式说明] │ │
│ └────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 📚 词库管理 │ │
│ │ [编辑词库 Tab] [导入/导出 Tab] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 【区域 3:生成控制】(始终显示) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 生成数量: [滑块 10-100] │ │
│ │ [生成关键词] [清空本模块结果] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 【区域 4:扩展功能】(条件显示:有关键词时) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 🌐 语义足迹扩展 │ │
│ │ - 扩展数量: [滑块] │ │
│ │ - [开始语义扩展] [合并策略: 追加/替换/交替] │ │
│ │ - [统计信息] [扩展详情] [覆盖面分析] │ │
│ └────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 🎯 话题集群生成 │ │
│ │ - 话题集群数量: [滑块] │ │
│ │ - [生成话题集群] │ │
│ │ - [统计] [集群列表] [关联关系] [网络图] [规划建议] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 【区域 5:关键词列表】(条件显示:有关键词时) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 📋 关键词列表 │ │
│ │ [DataFrame 表格] │ │
│ │ [下载关键词CSV] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 【区域 6:智能挖掘】(条件显示:有关键词时,折叠默认) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 🔍 智能关键词挖掘与趋势分析 │ │
│ │ [🌐 行业热点挖掘] [📊 竞争度分析] [📈 趋势预测] │ │
│ │ [💎 价值矩阵] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
组件顺序与交互流
交互流程 1:AI 生成模式(最简单)
1. 选择"AI生成"模式
2. 设置生成数量(默认 10)
3. 点击"生成关键词"
4. 查看关键词列表
5. (可选)使用扩展功能
交互流程 2:托词工具模式
1. 选择"托词工具"模式
2. 配置组合模式(多选)
3. 管理词库(编辑/导入)
4. 设置生成数量
5. 点击"生成关键词"
6. 查看关键词列表
交互流程 3:混合模式
1. 选择"混合模式"
2. 配置组合模式
3. 管理词库
4. 设置生成数量
5. 点击"生成关键词"(先托词生成,再 LLM 润色)
6. 查看关键词列表
7. (可选)使用扩展功能
紧凑布局规则
间距规则
# 区域间距
区域之间:st.markdown("---") # 1.5rem 间距(CSS 已定义)
# 容器内间距
with st.container(border=True):
# 容器内 padding: 1.5rem(CSS 已定义)
# 容器内元素间距:0.75rem
st.markdown("#### 标题") # margin-top: 0, margin-bottom: 0.75rem
# 控件间距:0.5rem
分组规则
# 主要功能区域:使用 container(border=True)
# 次要信息:使用 expander(默认折叠)
# 统计信息:使用 columns + metric(紧凑显示)
折叠规则
# 默认展开
- 模式选择
- 生成控制
- 关键词列表(如果有关键词)
# 默认折叠
- 组合模式说明(expander)
- 扩展详情(expander)
- 覆盖面分析(expander)
- 智能挖掘(整个区域,如果功能复杂)
问题清单(含严重级别)
🔴 P0 - 必改(逻辑漏洞/严重体验问题)
1. 空值检查不完整
- 位置:第 1064-1192 行(生成关键词逻辑)
- 问题:
generation_mode == "AI生成"时,未检查brand和advantages是否为空generation_mode == "托词工具"时,检查了空词库,但错误提示在生成后,应该在生成前阻止
- 影响:可能导致 API 调用失败或生成无效结果
- 修复:在
run_kw点击时,先验证所有必需参数
2. 状态同步问题
- 位置:第 1194-1867 行(扩展功能区域)
- 问题:
st.session_state.expanded_keywords在扩展后未清空,可能导致重复合并st.session_state.topic_clusters在生成新关键词后未清空,可能显示旧数据
- 影响:数据混乱,用户困惑
- 修复:在生成新关键词时,清空所有扩展/集群相关状态
3. 并发点击防护缺失
- 位置:所有按钮点击处理
- 问题:
- 用户快速点击"生成关键词"可能触发多次 API 调用
- 无 loading 状态保护
- 影响:重复请求、资源浪费、可能的数据覆盖
- 修复:使用
st.session_state标记处理中状态,禁用按钮
4. 错误提示不友好
- 位置:第 1180-1192 行(生成失败处理)
- 问题:
- 错误信息过于技术化("生成失败,可能的原因:...")
- 未提供具体解决建议
- 影响:用户不知道如何修复问题
- 修复:提供分场景的错误提示和操作建议
5. 缓存问题
- 位置:第 1107-1120 行(托词工具生成)
- 问题:
wordbanks每次从st.session_state读取,但更新词库后可能未同步selected_patterns可能过期
- 影响:使用旧配置生成,结果不符合预期
- 修复:在生成前重新加载最新配置
🟡 P1 - 建议(体验优化)
6. 布局分散
- 位置:整个 Tab 1
- 问题:
- 功能模块之间缺乏视觉分组
- 条件显示的功能(扩展/集群/挖掘)与主要功能混在一起
- 影响:信息过载,用户难以聚焦
- 修复:使用容器分组,明确区域划分
7. 重复输入
- 位置:第 1604 行(行业热点挖掘)
- 问题:
industry输入框默认值 "外贸ERP",但用户可能已在侧边栏配置了品牌信息- 未复用侧边栏的
brand信息
- 影响:用户需要重复输入
- 修复:默认使用
brand,允许覆盖
8. 加载态不明确
- 位置:所有异步操作
- 问题:
st.spinner文本不够具体("AI生成中..." vs "正在生成 20 个关键词...")- 无进度提示(对于大量关键词生成)
- 影响:用户不知道需要等待多久
- 修复:提供更详细的加载信息和进度估算
9. 默认值不合理
- 位置:第 1042 行(生成数量滑块)
- 问题:
- 默认值使用
st.session_state.kw_last_num,但首次使用时可能未初始化 - 范围 10-100,但用户可能需要更少或更多
- 默认值使用
- 影响:首次使用体验不佳
- 修复:确保默认值始终有效,考虑扩大范围或添加手动输入
10. 结果展示不清晰
- 位置:第 1566 行(关键词列表)
- 问题:
- DataFrame 显示所有关键词,但列表可能很长(100+)
- 未区分原始关键词和扩展关键词(虽然有 caption,但不够明显)
- 影响:难以快速查看和筛选
- 修复:添加分页、搜索、筛选功能
🟢 P2 - 可做(锦上添花)
11. 撤销功能缺失
- 位置:第 1060 行(清空按钮)
- 问题:
- "清空本模块结果" 不可撤销
- 用户误操作后无法恢复
- 影响:用户需要重新生成
- 修复:添加撤销功能或确认对话框
12. 批量操作缺失
- 位置:关键词列表
- 问题:
- 无法批量删除/导出/标记关键词
- 智能挖掘结果需要逐个添加
- 影响:效率低下
- 修复:添加多选和批量操作
13. 历史记录集成
- 位置:整个 Tab 1
- 问题:
- 生成的关键词未与 Tab 5(历史记录)深度集成
- 无法快速查看/恢复历史关键词
- 影响:无法复用历史数据
- 修复:在 Tab 1 添加"从历史记录加载"功能
14. 导出格式单一
- 位置:第 1574 行(下载 CSV)
- 问题:
- 仅支持 CSV 格式
- 未支持 JSON、TXT、Excel 等格式
- 影响:用户需要手动转换格式
- 修复:添加多格式导出选项
15. 快捷键支持
- 位置:整个 Tab 1
- 问题:
- 无键盘快捷键(如 Ctrl+Enter 生成)
- 无快速导航
- 影响:效率较低
- 修复:添加常用快捷键(Streamlit 限制,可能需 JS 扩展)
改动方案(含具体交互/文案/状态设计)
改动 1:去掉 Tab 名称中的序号
位置:第 913 行
改动前:
tab1, tab2, tab3, ... = st.tabs([
"1 关键词蒸馏",
"2 自动创作",
...
])
改动后:
tab1, tab2, tab3, ... = st.tabs([
"🎯 关键词蒸馏",
"✍️ 自动创作",
"🔧 文章优化",
"✅ 多模型验证",
"📚 历史记录",
"📊 AI 数据报表",
"⚙️ 工作流自动化",
"📦 GEO 资源库",
"🔄 平台同步",
"🛠️ 配置优化助手"
])
理由:去掉序号,保留 emoji,提升现代感和识别度
改动 2:优化布局结构(区域分组)
位置:第 918-1868 行(整个 Tab 1)
改动前:功能模块平铺,缺乏分组
改动后:
with tab1:
# ========== 区域 1:模式选择 ==========
st.markdown("### 🎯 生成模式")
generation_mode = st.radio(
"选择生成模式",
["AI生成", "托词工具", "混合模式"],
index=["AI生成", "托词工具", "混合模式"].index(st.session_state.kw_generation_mode),
horizontal=True,
key="kw_mode_radio"
)
st.session_state.kw_generation_mode = generation_mode
st.markdown("---")
# ========== 区域 2:配置区(条件显示) ==========
if generation_mode in ["托词工具", "混合模式"]:
# 组合模式选择
with st.container(border=True):
st.markdown("#### 📐 组合模式选择")
# ... 现有代码 ...
# 词库管理
with st.container(border=True):
st.markdown("#### 📚 词库管理")
# ... 现有代码 ...
st.markdown("---")
# ========== 区域 3:生成控制 ==========
with st.container(border=True):
st.markdown("#### ⚙️ 生成控制")
c1, c2, c3 = st.columns([2, 1, 1])
with c1:
st.session_state.kw_last_num = st.slider(
"生成数量", 10, 100, st.session_state.kw_last_num, key="kw_num"
)
with c2:
run_kw_disabled = (
(generation_mode != "托词工具" and (not st.session_state.cfg_valid or gen_llm is None))
or (generation_mode in ["托词工具", "混合模式"] and not st.session_state.get("selected_patterns"))
)
run_kw = st.button(
"🚀 生成关键词",
type="primary",
use_container_width=True,
disabled=run_kw_disabled,
key="kw_run",
)
with c3:
if st.button("🗑️ 清空结果", use_container_width=True, key="kw_clear"):
# 清空所有相关状态
st.session_state.keywords = []
st.session_state.expanded_keywords = []
st.session_state.topic_clusters = []
st.session_state.mined_keywords = []
st.toast("已清空所有关键词和相关数据")
st.rerun()
# 生成逻辑(改进错误处理和状态管理)
if run_kw:
# 参数验证
if generation_mode == "AI生成":
if not brand or not advantages:
st.error("❌ 请先在侧边栏配置品牌名称和核心优势")
st.stop()
# 防止并发点击
if st.session_state.get("kw_generating", False):
st.warning("⏳ 正在生成中,请勿重复点击")
st.stop()
st.session_state.kw_generating = True
# ... 生成逻辑(保持现有代码) ...
st.session_state.kw_generating = False
# ========== 区域 4:扩展功能(条件显示) ==========
if st.session_state.keywords:
st.markdown("---")
# 语义足迹扩展
with st.container(border=True):
st.markdown("#### 🌐 语义足迹扩展")
# ... 现有代码(改进状态管理) ...
# 话题集群生成
with st.container(border=True):
st.markdown("#### 🎯 话题集群生成")
# ... 现有代码(改进状态管理) ...
# ========== 区域 5:关键词列表(条件显示) ==========
if st.session_state.keywords:
st.markdown("---")
st.markdown("#### 📋 关键词列表")
# 添加搜索和筛选
search_col, filter_col = st.columns([3, 1])
with search_col:
search_term = st.text_input("🔍 搜索关键词", key="kw_search", placeholder="输入关键词搜索...")
with filter_col:
show_original = st.checkbox("仅显示原始关键词", key="kw_filter_original", value=False)
# 过滤关键词
display_keywords = st.session_state.keywords
if search_term:
display_keywords = [kw for kw in display_keywords if search_term.lower() in kw.lower()]
if show_original and st.session_state.expanded_keywords:
original_count = len(st.session_state.keywords) - len(st.session_state.expanded_keywords)
display_keywords = display_keywords[:original_count]
# 显示列表(分页)
if display_keywords:
page_size = 20
total_pages = (len(display_keywords) - 1) // page_size + 1
page = st.session_state.get("kw_page", 1)
page_col1, page_col2, page_col3 = st.columns([1, 2, 1])
with page_col2:
page = st.selectbox("页码", range(1, total_pages + 1), index=page - 1, key="kw_page_select")
start_idx = (page - 1) * page_size
end_idx = start_idx + page_size
page_keywords = display_keywords[start_idx:end_idx]
df = pd.DataFrame(page_keywords, columns=["长尾关键词/问题"])
st.dataframe(df, use_container_width=True, hide_index=True)
st.caption(f"显示第 {start_idx + 1}-{min(end_idx, len(display_keywords))} 条,共 {len(display_keywords)} 条关键词")
# 区分原始和扩展关键词
if st.session_state.expanded_keywords:
original_count = len(st.session_state.keywords) - len(st.session_state.expanded_keywords)
st.info(f"📌 原始关键词:{original_count} 个 | 🆕 扩展关键词:{len(st.session_state.expanded_keywords)} 个")
else:
st.info("未找到匹配的关键词")
# 下载按钮
st.download_button(
"📥 下载关键词 CSV",
pd.DataFrame(st.session_state.keywords, columns=["长尾关键词/问题"]).to_csv(index=False, encoding="utf-8-sig"),
f"{sanitize_filename(brand,40)}_keywords.csv",
mime="text/csv",
use_container_width=True,
key="kw_dl_csv",
)
# ========== 区域 6:智能挖掘(条件显示,默认折叠) ==========
if st.session_state.keywords:
st.markdown("---")
with st.expander("🔍 智能关键词挖掘与趋势分析", expanded=False):
st.caption("发现高价值关键词,分析竞争度,预测趋势,优化关键词策略")
# ... 现有代码(保持 tabs 结构) ...
else:
st.info("💡 提示:在左侧完成配置后,点击"生成关键词"开始使用。")
改动点:
- 明确区域划分(使用注释和分隔线)
- 改进状态管理(清空时清空所有相关状态)
- 添加参数验证和并发防护
- 添加搜索、筛选、分页功能
- 智能挖掘默认折叠(减少信息过载)
改动 3:改进错误处理和用户提示
位置:第 1064-1192 行(生成逻辑)
改动前:
if cleaned:
st.session_state.keywords = cleaned
st.success(f"生成完成({len(cleaned)} 条)")
else:
error_msg = "生成失败,可能的原因:\n"
# ... 通用错误信息
st.error(error_msg)
改动后:
if cleaned:
st.session_state.keywords = cleaned
# 清空扩展和集群相关状态
st.session_state.expanded_keywords = []
st.session_state.topic_clusters = []
st.session_state.mined_keywords = []
st.success(f"✅ 生成完成!共生成 {len(cleaned)} 个关键词")
st.balloons() # 成功动画(可选)
else:
# 分场景错误提示
if generation_mode == "AI生成":
st.error("""
❌ **AI 生成失败**
**可能原因:**
- API Key 配置错误或余额不足
- 网络连接问题
- 品牌名称或核心优势为空
**解决建议:**
1. 检查侧边栏的 API Key 配置
2. 确认品牌名称和核心优势已填写
3. 稍后重试或联系技术支持
""")
elif generation_mode == "托词工具":
wordbanks = st.session_state.wordbanks or st.session_state.keyword_tool.load_wordbanks()
empty_banks = [k for k, v in wordbanks.items() if not v]
if empty_banks:
st.error(f"""
❌ **词库为空**
以下词库为空,请先添加词汇:
- {', '.join(empty_banks)}
**操作步骤:**
1. 点击"词库管理"
2. 选择空的词库类型
3. 添加至少 3-5 个词汇
4. 点击"更新词库"
5. 重新生成关键词
""")
elif not st.session_state.get("selected_patterns"):
st.error("""
❌ **未选择组合模式**
请至少选择一个组合模式:
1. 在"组合模式选择"区域
2. 勾选至少一个模式
3. 重新生成关键词
""")
elif generation_mode == "混合模式":
# 类似托词工具的错误处理
# ...
改动点:
- 分场景错误提示(更具体)
- 提供解决建议(可操作)
- 使用 markdown 格式化(更易读)
- 清空相关状态(避免数据混乱)
改动 4:优化加载状态和进度提示
位置:所有异步操作
改动前:
with st.spinner("AI生成中..."):
# ...
改动后:
# 使用进度条和详细状态
progress_bar = st.progress(0)
status_text = st.empty()
with st.spinner(""):
status_text.text("🔄 正在生成关键词...")
progress_bar.progress(10)
# 模拟进度(实际应根据 API 响应调整)
if generation_mode == "AI生成":
status_text.text("🤖 调用 AI 模型生成关键词...")
progress_bar.progress(30)
# ... 实际生成逻辑
progress_bar.progress(80)
status_text.text("✨ 处理生成结果...")
progress_bar.progress(100)
elif generation_mode == "托词工具":
status_text.text("🔧 加载词库和组合模式...")
progress_bar.progress(20)
status_text.text("🔄 生成关键词组合...")
progress_bar.progress(60)
status_text.text("✨ 去重和筛选...")
progress_bar.progress(100)
# ...
status_text.text(f"✅ 完成!生成 {len(cleaned)} 个关键词")
progress_bar.empty()
改动点:
- 使用进度条(视觉反馈)
- 详细状态文本(用户知道在做什么)
- 分阶段进度(更真实)
改动 5:改进默认值和初始化
位置:第 1042 行(生成数量滑块)
改动前:
st.session_state.kw_last_num = st.slider(
"生成数量", 10, 100, st.session_state.kw_last_num, key="kw_num"
)
改动后:
# 确保默认值有效
ss_init("kw_last_num", 20) # 默认 20 个
# 滑块 + 手动输入
col1, col2 = st.columns([3, 1])
with col1:
st.session_state.kw_last_num = st.slider(
"生成数量",
5, 200, # 扩大范围
st.session_state.kw_last_num,
key="kw_num",
help="建议范围:10-50 个关键词"
)
with col2:
manual_num = st.number_input(
"手动输入",
min_value=5,
max_value=200,
value=st.session_state.kw_last_num,
key="kw_num_manual"
)
if manual_num != st.session_state.kw_last_num:
st.session_state.kw_last_num = manual_num
st.rerun()
改动点:
- 确保默认值初始化
- 扩大范围(5-200)
- 添加手动输入选项(精确控制)
- 提供建议范围(帮助用户)
测试用例清单
测试用例 1:AI 生成模式 - 正常流程
前置条件:
- 侧边栏已配置 API Key、品牌名称、核心优势
- Tab 1 处于默认状态
测试步骤:
- 选择"AI生成"模式(默认)
- 设置生成数量为 20
- 点击"生成关键词"按钮
- 等待生成完成
预期结果:
- ✅ 显示加载状态(进度条 + 状态文本)
- ✅ 生成 20 个关键词(或接近 20 个,取决于去重)
- ✅ 显示成功提示:"✅ 生成完成!共生成 X 个关键词"
- ✅ 关键词列表区域显示 DataFrame
- ✅ 可以下载 CSV 文件
测试用例 2:AI 生成模式 - 参数缺失
前置条件:
- 侧边栏未配置品牌名称或核心优势
- Tab 1 处于默认状态
测试步骤:
- 选择"AI生成"模式
- 设置生成数量为 20
- 点击"生成关键词"按钮
预期结果:
- ✅ 显示错误提示:"❌ 请先在侧边栏配置品牌名称和核心优势"
- ✅ 不执行 API 调用
- ✅ 按钮保持可用状态(允许修复后重试)
测试用例 3:托词工具模式 - 正常流程
前置条件:
- 侧边栏已配置品牌名称、核心优势
- 词库已初始化(有词汇)
- 至少选择一个组合模式
测试步骤:
- 选择"托词工具"模式
- 在"组合模式选择"中勾选至少一个模式
- 设置生成数量为 30
- 点击"生成关键词"按钮
- 等待生成完成
预期结果:
- ✅ 显示"组合模式选择"和"词库管理"区域
- ✅ 生成 30 个关键词(或接近,取决于组合结果)
- ✅ 显示成功提示
- ✅ 关键词列表显示结果
测试用例 4:托词工具模式 - 词库为空
前置条件:
- 侧边栏已配置
- 词库为空(所有词库类型都没有词汇)
测试步骤:
- 选择"托词工具"模式
- 选择一个组合模式
- 点击"生成关键词"按钮
预期结果:
- ✅ 显示错误提示:"❌ 词库为空",列出空的词库类型
- ✅ 提供解决建议(添加词汇的步骤)
- ✅ 不执行生成逻辑
测试用例 5:托词工具模式 - 未选择组合模式
前置条件:
- 侧边栏已配置
- 词库有词汇
- 未选择任何组合模式
测试步骤:
- 选择"托词工具"模式
- 不选择任何组合模式(取消所有勾选)
- 点击"生成关键词"按钮
预期结果:
- ✅ "生成关键词"按钮被禁用(或点击后显示错误)
- ✅ 显示错误提示:"❌ 未选择组合模式"
- ✅ 提供解决建议
测试用例 6:混合模式 - 正常流程
前置条件:
- 侧边栏已配置 API Key、品牌名称、核心优势
- 词库已初始化
- 至少选择一个组合模式
测试步骤:
- 选择"混合模式"
- 配置组合模式和词库
- 设置生成数量为 25
- 点击"生成关键词"按钮
- 观察两个阶段的加载状态
预期结果:
- ✅ 显示"托词生成中..."状态
- ✅ 显示"LLM 润色中..."状态
- ✅ 生成 25 个关键词(经过润色)
- ✅ 显示成功提示
测试用例 7:并发点击防护
前置条件:
- 侧边栏已配置
- Tab 1 处于可生成状态
测试步骤:
- 点击"生成关键词"按钮
- 在加载过程中,快速再次点击按钮(模拟并发)
预期结果:
- ✅ 第一次点击后,按钮被禁用或显示"正在生成中"
- ✅ 第二次点击被忽略或显示警告:"⏳ 正在生成中,请勿重复点击"
- ✅ 只执行一次 API 调用
- ✅ 生成完成后,按钮恢复可用
测试用例 8:语义扩展功能
前置条件:
- 已生成关键词(至少 10 个)
- 侧边栏已配置 API Key
测试步骤:
- 滚动到"语义足迹扩展"区域
- 设置扩展数量为 30
- 选择合并策略为"追加"
- 点击"开始语义扩展"按钮
- 等待扩展完成
预期结果:
- ✅ 显示加载状态:"正在扩展关键词(目标:30 个)..."
- ✅ 扩展完成后,关键词列表总数增加
- ✅ 显示成功提示:"✅ 语义扩展完成!新增 X 个关键词,总计 Y 个"
- ✅ 显示扩展统计信息(6 个指标)
- ✅ 可以查看扩展详情和覆盖面分析
测试用例 9:话题集群生成
前置条件:
- 已生成关键词(至少 20 个)
- 侧边栏已配置 API Key
测试步骤:
- 滚动到"话题集群生成"区域
- 设置话题集群数量为 5
- 点击"生成话题集群"按钮
- 等待生成完成
预期结果:
- ✅ 显示加载状态
- ✅ 生成 5 个话题集群
- ✅ 显示统计信息(4 个指标)
- ✅ 显示话题集群列表(可展开查看详情)
- ✅ 显示话题关联关系表格
- ✅ 显示话题网络图(可视化)
- ✅ 显示内容规划建议
测试用例 10:清空功能
前置条件:
- 已生成关键词
- 已执行扩展或集群生成
测试步骤:
- 点击"清空结果"按钮
- 观察页面状态
预期结果:
- ✅ 显示 Toast 提示:"已清空所有关键词和相关数据"
- ✅
st.session_state.keywords被清空 - ✅
st.session_state.expanded_keywords被清空 - ✅
st.session_state.topic_clusters被清空 - ✅
st.session_state.mined_keywords被清空 - ✅ 关键词列表区域消失
- ✅ 扩展功能区域消失
- ✅ 页面显示提示:"💡 提示:在左侧完成配置后,点击"生成关键词"开始使用。"
测试用例 11:搜索和筛选功能
前置条件:
- 已生成关键词(包含扩展关键词)
测试步骤:
- 在关键词列表的搜索框输入关键词(如"AI")
- 观察列表过滤结果
- 勾选"仅显示原始关键词"
- 观察列表变化
预期结果:
- ✅ 搜索框实时过滤关键词
- ✅ 显示匹配的关键词数量
- ✅ 勾选"仅显示原始关键词"后,只显示原始关键词(不包含扩展的)
- ✅ 分页功能正常工作(如果关键词 > 20 个)
测试用例 12:智能挖掘功能
前置条件:
- 已生成关键词
- 侧边栏已配置 API Key
测试步骤:
- 展开"智能关键词挖掘与趋势分析"区域
- 切换到"🌐 行业热点挖掘"标签
- 输入行业领域(如"AI工具")
- 设置挖掘数量为 20
- 点击"开始挖掘"按钮
- 等待挖掘完成
- 点击某个挖掘结果的"添加"按钮
预期结果:
- ✅ 显示加载状态
- ✅ 挖掘完成,显示挖掘结果列表
- ✅ 每个结果显示关键词、类别、意图、预估价值
- ✅ 点击"添加"后,关键词被添加到主列表
- ✅ 显示成功提示:"已添加"
- ✅ 页面刷新,新关键词出现在列表中
测试用例 13:词库管理 - 编辑词库
前置条件:
- 选择"托词工具"或"混合模式"
- 词库已初始化
测试步骤:
- 在"词库管理"区域,选择"编辑词库"标签
- 选择一个词库类型(如"核心词")
- 在文本框中添加新词汇(每行一个)
- 点击"更新词库"按钮
- 观察成功提示
- 重新生成关键词,验证新词汇被使用
预期结果:
- ✅ 显示当前词库内容
- ✅ 可以编辑文本
- ✅ 点击"更新词库"后,显示成功提示:"核心词 已更新(X 个词汇)"
- ✅ 新词汇在生成关键词时被使用
测试用例 14:词库管理 - 导入导出
前置条件:
- 选择"托词工具"或"混合模式"
- 词库已初始化
测试步骤:
- 在"词库管理"区域,选择"导入/导出"标签
- 点击"导出词库(JSON)"按钮
- 下载 JSON 文件
- 修改 JSON 文件(添加新词汇)
- 点击"导入词库(JSON)"按钮
- 上传修改后的 JSON 文件
- 观察导入结果
预期结果:
- ✅ 成功下载 JSON 文件
- ✅ JSON 文件格式正确(包含所有词库类型)
- ✅ 上传后显示成功提示:"词库导入成功!"
- ✅ 页面刷新,新词库内容生效
- ✅ 如果 JSON 格式错误,显示错误提示
测试用例 15:边界条件测试
测试步骤:
- 生成数量设置为最小值(5)
- 生成数量设置为最大值(200)
- 生成数量设置为手动输入(如 150)
- 在空状态下点击"生成关键词"(无配置)
- 在 API Key 无效时点击"生成关键词"
预期结果:
- ✅ 最小值/最大值正常工作
- ✅ 手动输入值被正确应用
- ✅ 空状态显示友好提示
- ✅ API Key 无效时显示具体错误信息
最小改动 MVP 优化清单(1 天内完成)
优先级 P0(必须完成,约 4 小时)
1. 去掉 Tab 名称序号(5 分钟)
- 修改第 913 行,去掉序号,保留 emoji
- 测试所有 Tab 切换正常
2. 修复空值检查(30 分钟)
- 在
run_kw点击时,验证所有必需参数 - 添加分场景错误提示
- 测试各种缺失参数的情况
3. 修复状态同步问题(30 分钟)
- 在生成新关键词时,清空扩展/集群相关状态
- 在清空按钮中,清空所有相关状态
- 测试状态同步
4. 添加并发点击防护(30 分钟)
- 使用
st.session_state.kw_generating标记 - 在生成过程中禁用按钮
- 测试并发点击
5. 优化错误提示(1 小时)
- 分场景错误提示(AI生成/托词工具/混合模式)
- 提供解决建议
- 使用 markdown 格式化
- 测试各种错误场景
6. 修复缓存问题(30 分钟)
- 在生成前重新加载最新配置
- 测试词库更新后的生成
7. 改进布局结构(1 小时)
- 添加区域划分(注释 + 分隔线)
- 使用容器分组主要功能
- 智能挖掘默认折叠
- 测试布局显示
优先级 P1(建议完成,约 2 小时)
8. 添加搜索和筛选(30 分钟)
- 添加搜索框
- 添加"仅显示原始关键词"筛选
- 测试搜索和筛选功能
9. 改进加载状态(30 分钟)
- 使用进度条和详细状态文本
- 分阶段进度提示
- 测试加载状态显示
10. 优化默认值(20 分钟)
- 确保
kw_last_num默认值初始化 - 扩大滑块范围(5-200)
- 测试默认值
11. 改进结果展示(40 分钟)
- 添加分页功能(如果关键词 > 20 个)
- 改进原始/扩展关键词区分
- 测试结果展示
优先级 P2(可选,约 1 小时)
12. 添加撤销功能(30 分钟)
- 在清空按钮添加确认对话框
- 或添加撤销按钮(保存上一次状态)
- 测试撤销功能
13. 优化行业热点挖掘默认值(10 分钟)
- 默认使用
brand作为行业领域 - 允许覆盖
- 测试默认值
14. 添加多格式导出(20 分钟)
- 添加 JSON 格式导出
- 添加 TXT 格式导出
- 测试导出功能
总结
核心改动
- 去掉序号:Tab 名称去掉序号,保留 emoji,提升现代感
- 布局优化:明确区域划分,使用容器分组,智能挖掘默认折叠
- 逻辑修复:空值检查、状态同步、并发防护、错误提示
- 体验提升:搜索筛选、加载状态、分页、默认值优化
预计工作量
- P0 改动:4 小时(必须完成)
- P1 改动:2 小时(建议完成)
- P2 改动:1 小时(可选)
- 总计:7 小时(1 天内可完成 P0 + P1)
风险控制
- 逐步实施:先完成 P0,测试通过后再做 P1
- 保持功能:只改布局和体验,不改核心逻辑
- 充分测试:每个改动后立即测试,确保功能正常
文档版本:v1.0
最后更新:2026-01-28
下一步:开始实施 P0 改动