# MiroFish 前端功能演示

## 首页功能详解

### 1. 页面整体布局

```
┌─────────────────────────────────────────────────┐
│                                                 │
│              [MiroFish Logo]                    │
│                                                 │
│       上传任意报告，模拟世界即刻开始              │
│                                                 │
├─────────────────────────────────────────────────┤
│                                                 │
│  模拟需求                                        │
│  ┌───────────────────────────────────────────┐ │
│  │ 请描述您的模拟需求...                     │ │
│  │                                           │ │
│  │                                           │ │
│  └───────────────────────────────────────────┘ │
│                                                 │
│  项目名称 (可选)                                 │
│  ┌───────────────────────────────────────────┐ │
│  │ 为您的项目命名                            │ │
│  └───────────────────────────────────────────┘ │
│                                                 │
│  上传文档                                        │
│  ┌───────────────────────────────────────────┐ │
│  │         📤                                 │ │
│  │  点击或拖拽文件到此处                      │ │
│  │  支持 PDF、Markdown、TXT 格式              │ │
│  └───────────────────────────────────────────┘ │
│                                                 │
│  额外说明 (可选)                                 │
│  ┌───────────────────────────────────────────┐ │
│  │ 如有其他需要补充的信息...                  │ │
│  └───────────────────────────────────────────┘ │
│                                                 │
│  ┌───────────────────────────────────────────┐ │
│  │           开 始 模 拟                      │ │
│  └───────────────────────────────────────────┘ │
│                                                 │
└─────────────────────────────────────────────────┘
```

### 2. 交互功能说明

#### 2.1 文件上传

**支持方式**:
1. **点击上传**: 点击上传区域,弹出文件选择对话框
2. **拖拽上传**: 直接拖拽文件到上传区域

**支持格式**:
- PDF文档 (.pdf)
- Markdown文档 (.md)
- 纯文本文档 (.txt)

**上传特性**:
- ✅ 支持多文件上传
- ✅ 显示文件名和大小
- ✅ 可以删除已选择的文件
- ✅ 自动过滤不支持的格式
- ✅ 拖拽时高亮显示上传区域

**示例**:
```
上传后显示:
┌─────────────────────────────────────────┐
│ 📄 report.pdf          2.5 MB      [×] │
│ 📄 analysis.md         1.2 MB      [×] │
└─────────────────────────────────────────┘
```

#### 2.2 表单验证

**必填项检查**:
- ❌ 未填写模拟需求 → 按钮禁用
- ❌ 未上传文件 → 按钮禁用
- ✅ 两者都完成 → 按钮可点击

**可选项**:
- 项目名称(留空则自动生成)
- 额外说明(留空则不传递)

**状态提示**:
- 按钮禁用时:灰色不可点击
- 按钮可用时:黑色背景,hover变白色背景

#### 2.3 提交流程

**步骤1: 用户点击"开始模拟"**
```
按钮状态变为:
┌─────────────────────────────┐
│  ⌛ 处理中...              │
└─────────────────────────────┘
```

**步骤2: 构建FormData**
```javascript
FormData包含:
- files: [file1, file2, ...]
- simulation_requirement: "用户输入的需求"
- project_name: "项目名称" (可选)
- additional_context: "额外说明" (可选)
```

**步骤3: 调用API**
```
POST /api/graph/ontology/generate
Content-Type: multipart/form-data

自动重试机制:
第1次失败 → 等待1秒 → 重试
第2次失败 → 等待2秒 → 重试
第3次失败 → 等待4秒 → 重试
第4次失败 → 显示错误
```

**步骤4: 成功响应**
```json
{
  "success": true,
  "data": {
    "project_id": "proj_abc123",
    "project_name": "项目名称",
    "ontology": { ... },
    ...
  }
}
```

**步骤5: 页面跳转**
```
跳转到: /process/proj_abc123
```

#### 2.4 错误处理

**网络错误**:
```
┌───────────────────────────────────────┐
│ ⚠ 提交失败,请检查网络连接或稍后重试    │
└───────────────────────────────────────┘
```

**API错误**:
```
┌───────────────────────────────────────┐
│ ⚠ 生成本体失败,请重试                 │
└───────────────────────────────────────┘
```

**文件格式错误**:
```
┌───────────────────────────────────────┐
│ ⚠ 部分文件格式不支持,已自动过滤       │
└───────────────────────────────────────┘
```

### 3. 设计细节

#### 3.1 颜色方案
```css
/* 主色调 */
黑色: #000000 (文字、边框、按钮)
白色: #FFFFFF (背景、按钮hover)
灰色: #666666 (次要文字)
浅灰: #f5f5f5 (禁用背景)

/* 错误色 */
红色: #ff0000 (错误提示边框和文字)
浅红: #fff5f5 (错误提示背景)
```

#### 3.2 边框样式
```css
/* 输入框 */
border: 1px solid #000000

/* 输入框聚焦 */
border: 2px solid #000000

/* 上传区域 */
border: 2px dashed #000000

/* 上传区域hover */
border: 2px dashed #333333
background: #fafafa

/* 上传区域拖拽中 */
border: 2px solid #000000
background: #f0f0f0
```

#### 3.3 字体样式
```css
/* Logo标语 */
font-size: 1.5rem (24px)
font-weight: 300
letter-spacing: 0.05em

/* 标签 */
font-size: 0.95rem (15.2px)
font-weight: 500
letter-spacing: 0.02em

/* 输入框 */
font-size: 0.95rem (15.2px)

/* 按钮 */
font-size: 1.1rem (17.6px)
font-weight: 500
letter-spacing: 0.1em
```

#### 3.4 间距设计
```css
/* 区块间距 */
margin-bottom: 1.5rem (24px)

/* 内边距 */
表单区域: padding: 2.5rem (40px)
输入框: padding: 0.75rem (12px)
按钮: padding: 1rem (16px)
```

### 4. 响应式适配

#### 桌面端 (>= 768px)
```
容器最大宽度: 800px
表单内边距: 2.5rem
Logo最大宽度: 400px
```

#### 移动端 (< 768px)
```
容器宽度: 100%
表单内边距: 1.5rem
Logo最大宽度: 300px
标语字号: 1.2rem
```

### 5. 动画效果

#### 加载动画
```css
@keyframes spin {
  to { transform: rotate(360deg); }
}

.loading-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid #ffffff;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
```

#### 按钮hover
```css
transition: all 0.3s;

/* Normal */
background: #000000;
color: #ffffff;

/* Hover */
background: #ffffff;
color: #000000;
```

#### 输入框焦点
```css
transition: all 0.2s;

/* Normal */
border: 1px solid #000000;

/* Focus */
border: 2px solid #000000;
```

## 第二页功能详解

### 1. 页面布局

```
┌───────────────────┬─────────────────────────┐
│                   │                         │
│   实时图谱        │  Step 1 - 现实种子构建  │
│                   │                         │
│  ┌─────────────┐  │  ① 文档分析 ✓           │
│  │             │  │  正在分析上传的文档...  │
│  │   图谱      │  │                         │
│  │   可视化    │  │  ② 本体生成 ⌛          │
│  │             │  │  使用LLM生成本体...     │
│  │             │  │                         │
│  └─────────────┘  │  ③ 图谱构建             │
│                   │  待处理...              │
│  节点数: 50       │                         │
│  关系数: 120      │  ④ 完成                 │
│                   │  待处理...              │
│                   │                         │
│                   │  ───────────────────   │
│                   │  项目信息                │
│                   │  项目名称: ...          │
│                   │  项目ID: proj_xxx       │
│                   │  状态: graph_building   │
│                   │                         │
└───────────────────┴─────────────────────────┘
```

### 2. 自动化流程

**页面加载**:
1. 从URL获取projectId
2. 调用 `GET /api/graph/project/{projectId}`
3. 根据项目状态更新UI

**状态机**:
```
created → ontology_generated → graph_building → graph_completed
   ↓            ↓                    ↓               ↓
  步骤1        步骤2                步骤3           步骤4
```

**自动触发图谱构建**:
```javascript
if (status === 'ontology_generated' && !graph_id) {
  // 自动调用 POST /api/graph/build
  await buildGraph({ project_id })
}
```

**轮询任务状态**:
```javascript
setInterval(() => {
  // 每2秒调用 GET /api/graph/task/{taskId}
  const task = await getTaskStatus(taskId)
  // 更新进度显示
}, 2000)
```

**加载图谱数据**:
```javascript
if (status === 'graph_completed' && graph_id) {
  // 调用 GET /api/graph/data/{graphId}
  const graphData = await getGraphData(graph_id)
}
```

### 3. 步骤指示器

**未开始状态**:
```
○ 步骤标题
  描述文字
  opacity: 0.4
```

**进行中状态**:
```
● 步骤标题
  描述文字
  进度信息 (45%)
  opacity: 1.0
  background: #000000 (number)
  color: #ffffff (number)
```

**已完成状态**:
```
● 步骤标题
  描述文字
  已完成 ✓
  opacity: 1.0
  background: #000000 (number)
```

## 使用示例

### 完整流程演示

**场景**: 模拟武汉大学撤销处分事件的舆情走向

**步骤1**: 打开首页
```
访问: http://localhost:3000
```

**步骤2**: 填写表单
```
模拟需求: "模拟武汉大学撤销处分通告发布后的舆情走向"
项目名称: "武汉大学舆情分析"
上传文档: report.pdf (关于事件的背景报告)
```

**步骤3**: 提交
```
点击"开始模拟"按钮
等待API响应(约5-30秒)
```

**步骤4**: 查看处理
```
自动跳转到: /process/proj_abc123
观察四个步骤的执行进度
等待图谱构建完成(约1-5分钟)
```

**步骤5**: 完成
```
所有步骤显示"已完成"
左侧展示图谱节点和关系统计
```

## 技术细节

### API重试机制
```javascript
export const requestWithRetry = async (
  requestFn,
  maxRetries = 3,
  delay = 1000
) => {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await requestFn()
    } catch (error) {
      if (i === maxRetries - 1) throw error
      
      const waitTime = delay * Math.pow(2, i)
      await new Promise(resolve => setTimeout(resolve, waitTime))
    }
  }
}
```

### 文件上传处理
```javascript
// 构建FormData
const formDataObj = new FormData()

// 添加文件
files.value.forEach(file => {
  formDataObj.append('files', file)
})

// 添加文本字段
formDataObj.append('simulation_requirement', requirement)
```

### 轮询实现
```javascript
let pollTimer = setInterval(async () => {
  const response = await getTaskStatus(taskId)
  
  if (response.data.status === 'completed') {
    clearInterval(pollTimer)
    // 处理完成逻辑
  }
}, 2000)

// 组件卸载时清理
onUnmounted(() => {
  if (pollTimer) clearInterval(pollTimer)
})
```

## 常见问题

### Q: 上传文件后看不到文件列表?
A: 检查文件格式是否支持(PDF、MD、TXT),不支持的格式会被自动过滤

### Q: 点击"开始模拟"没有反应?
A: 检查是否填写了模拟需求和上传了文件,两者都是必填项

### Q: 页面一直显示"处理中"?
A: 
1. 检查后端服务是否正常运行
2. 查看浏览器控制台是否有错误信息
3. 检查网络连接

### Q: 图谱构建一直不完成?
A: 
1. 图谱构建可能需要1-5分钟,请耐心等待
2. 查看右侧进度信息
3. 如果超过10分钟,可能是后端处理失败,查看后端日志

## 性能优化建议

1. **大文件上传**: 建议单个文件不超过10MB
2. **网络优化**: 使用稳定的网络连接
3. **浏览器**: 推荐使用Chrome浏览器
4. **并发限制**: 避免同时打开多个模拟任务

---

**文档更新**: 2025-12-10
**版本**: v1.0.0
