diff --git a/docs/architecture.md b/docs/architecture.md index 586a288..086396b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -9,6 +9,7 @@ │ │ index.html (单文件 SPA) │ │ │ │ ┌─────────┐ ┌──────────┐ ┌─────────────┐ │ │ │ │ │ 导航栏 │ │ 做题区域 │ │ 导入模态框 │ │ │ +│ │ │ │ │ [复制题目]│ │ [提示词模板] │ │ │ │ │ └────┬────┘ └─────┬────┘ └──────┬──────┘ │ │ │ └───────┼─────────────┼──────────────┼──────────┘ │ └──────────┼─────────────┼──────────────┼─────────────┘ @@ -256,7 +257,7 @@ examination/ │ ▶ 其他主题 │ │ 重置 全部显示 提交全部 │ │ │ │ └────────────────────────┘ │ │ │ ┌─ Question Card ────────┐ │ -│ ──────── │ │ #1 ★★★ │ │ +│ ──────── │ │ #1 [📋复制] ★★★ │ │ │ 📥 导入 │ │ 题干 [____] │ │ │ │ │ [检查] [显示答案] │ │ │ │ │ 💡 解析... │ │ @@ -283,9 +284,19 @@ fetch topics/{slug}/{type}.json (并行) ──→ 合并 questions 数组 ▼ renderQuiz() ──→ 渲染 Tab 栏 + 按当前 Tab 过滤题目卡片 │ - │ 用户交互(选择/输入/检查/显示答案/切换 Tab) + │ 用户交互(选择/输入/检查/显示答案/切换 Tab/复制题目) ▼ answers / activeTab 状态更新 ──→ re-render + +复制题目流程: + 用户点击 [📋 复制题目] ──→ copyQuestionPrompt(qId) + ──→ 按题型组织提示词(题干 + 选项/代码/子问题) + ──→ navigator.clipboard.writeText() ──→ 按钮变为 ✅ 已复制 + +导入提示词流程: + 用户打开导入弹窗 ──→ 点击 [📋 复制 AI 生成提示词] + ──→ 选择题型 ──→ 预览提示词模板 ──→ 复制到剪贴板 + ──→ 粘贴到外部 AI ──→ 获取 JSON ──→ 粘贴回导入框 ``` ### 4.3 状态管理 @@ -329,6 +340,17 @@ let activeTab = 'all'; // 当前 Tab:'all' 或题型名称 ### 5.1 非 Agent 环境(手动 LLM 对话) +**方式一:通过前端导入页面** + +1. 点击侧边栏底部「📥 导入题目」按钮 +2. 展开「📋 复制 AI 生成提示词」区域,选择目标题型 +3. 点击「复制提示词」,将包含完整 JSON Schema 的提示词复制到剪贴板 +4. 将提示词粘贴到外部 AI(ChatGPT / Claude 等),按需修改主题、数量等占位符 +5. 获取 AI 返回的 JSON 后,粘贴回导入弹窗的文本框 +6. 点击「导入」,题目将临时加载到当前会话 + +**方式二:通过 schema 模板文件** + 1. 打开 `schema/prompt-template.md`,复制提示词模板 2. 替换 `{topic_name}`、`{question_type}`、`{count}` 等变量 3. 将提示词发送给 LLM(ChatGPT / Claude 等) diff --git a/docs/requirements.md b/docs/requirements.md index af90ceb..5174a98 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -37,6 +37,8 @@ | 重置 | 清除所有作答状态 | | 进度统计 | 显示已答/正确/错误/待答数量和进度条 | | 自定义导入 | 弹窗粘贴 JSON 或上传文件,临时加入当前会话 | +| 复制题目提示词 | 题目卡片一键复制格式化的提示词,可在外部 AI 获取解析 | +| 导入提示词模板 | 导入弹窗提供 7 种题型的 AI 生成提示词模板,一键复制 | ### 3.2 题型支持 @@ -64,7 +66,7 @@ | 功能 | 说明 | |------|------| -| 提示词模板 | 提供标准化的 LLM 提示词,用于非 Agent 环境生成题目 | +| 提示词模板 | 提供标准化的 LLM 提示词,用于非 Agent 环境生成题目(前端导入页内置) | | JSON Schema | 定义完整的题目 JSON Schema,用于格式校验 | | Skill 复用 | 沉淀为 Claude Code Skill,支持 generate / validate / batch-generate | diff --git a/index.html b/index.html index 8e8800f..2859c75 100644 --- a/index.html +++ b/index.html @@ -163,6 +163,26 @@ body { font-family: -apple-system, 'Segoe UI', sans-serif; background: var(--bg) .file-input { display: block; width: 100%; padding: 12px; border: 1px dashed var(--surface2); border-radius: 8px; text-align: center; color: var(--text2); cursor: pointer; font-size: 13px; } .file-input:hover { border-color: var(--accent); } +/* Copy button in question card */ +.q-header .copy-btn { padding: 3px 10px; font-size: 12px; border-radius: 6px; border: 1px solid var(--surface2); background: transparent; color: var(--text2); cursor: pointer; transition: all 0.2s; white-space: nowrap; } +.q-header .copy-btn:hover { border-color: var(--accent); color: var(--accent); } +.q-header .copy-btn.copied { border-color: var(--green); color: var(--green); } + +/* Import prompt section */ +.prompt-section { margin-bottom: 16px; border: 1px solid var(--surface2); border-radius: 8px; overflow: hidden; } +.prompt-toggle { width: 100%; padding: 10px 14px; background: var(--bg); border: none; color: var(--text2); cursor: pointer; font-size: 13px; text-align: left; display: flex; align-items: center; gap: 6px; transition: color 0.2s; } +.prompt-toggle:hover { color: var(--text); } +.prompt-toggle .chevron { font-size: 10px; transition: transform 0.2s; margin-left: auto; } +.prompt-section.open .prompt-toggle .chevron { transform: rotate(90deg); } +.prompt-body { display: none; padding: 12px 14px; border-top: 1px solid var(--surface2); } +.prompt-section.open .prompt-body { display: block; } +.prompt-type-select { width: 100%; padding: 8px 10px; border-radius: 6px; border: 1px solid var(--surface2); background: var(--surface); color: var(--text); font-size: 13px; margin-bottom: 10px; outline: none; } +.prompt-type-select:focus { border-color: var(--accent); } +.prompt-preview { background: var(--bg); border: 1px solid var(--surface2); border-radius: 6px; padding: 10px; font-size: 12px; font-family: monospace; color: var(--text2); max-height: 200px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; line-height: 1.5; margin-bottom: 10px; } +.prompt-copy-btn { width: 100%; padding: 8px; border-radius: 6px; border: 1px solid var(--accent); background: transparent; color: var(--accent); cursor: pointer; font-size: 13px; font-weight: 600; transition: all 0.2s; } +.prompt-copy-btn:hover { background: var(--accent); color: white; } +.prompt-copy-btn.copied { border-color: var(--green); color: var(--green); background: transparent; } + /* Responsive */ @media (max-width: 768px) { .app { flex-direction: column; } @@ -199,7 +219,28 @@ body { font-family: -apple-system, 'Segoe UI', sans-serif; background: var(--bg)