# 项目负责人数据迁移指南

**日期**: 2025-10-24  
**问题**: 项目列表中的"负责人"列显示"未分配"

---

## 🔍 问题原因

现有项目在数据库中还没有 `assignee` 或 `department` 字段，导致显示"未分配"。

---

## ✅ 解决方案

### 方案1: 使用迁移脚本（推荐）

**步骤**:

1. **打开浏览器控制台**
   - 访问：`http://localhost:4200/admin/project-management`
   - 按 `F12` 打开开发者工具
   - 切换到"Console"标签

2. **运行迁移脚本**
   ```javascript
   // 1. 检查项目状态
   const ProjectMigrationService = await import('./src/app/pages/admin/services/project-migration.service').then(m => m.ProjectMigrationService);
   const migrationService = new ProjectMigrationService();
   
   // 查看需要迁移的项目数量
   const status = await migrationService.checkProjectsStatus();
   console.log('需要迁移的项目:', status.needsMigration);
   
   // 2. 执行迁移
   const result = await migrationService.migrateProjectAssignees();
   console.log('迁移结果:', result);
   ```

3. **刷新页面**
   - 按 `Ctrl+Shift+R` 强制刷新
   - 查看项目列表，"负责人"列应显示组长名字

---

### 方案2: Angular注入方式（如果方案1不work）

**步骤**:

1. **修改项目管理组件，添加迁移按钮**

在 `src/app/pages/admin/project-management/project-management.ts` 中添加：

```typescript
import { ProjectMigrationService } from '../services/project-migration.service';

export class ProjectManagement {
  constructor(
    private projectService: ProjectService,
    private migrationService: ProjectMigrationService // ✅ 添加
  ) {}
  
  // ✅ 添加迁移方法
  async migrateProjects() {
    const confirmed = confirm('确定要批量更新所有项目的负责人吗？');
    if (!confirmed) return;
    
    try {
      const result = await this.migrationService.migrateProjectAssignees();
      alert(`迁移完成！\n总计: ${result.total}\n成功: ${result.success}\n失败: ${result.failed}`);
      
      // 刷新项目列表
      await this.loadProjects();
    } catch (error) {
      alert('迁移失败: ' + error);
    }
  }
}
```

2. **在HTML中添加按钮**

在 `src/app/pages/admin/project-management/project-management.html` 顶部添加：

```html
<button (click)="migrateProjects()" class="btn btn-warning">
  🔧 批量更新负责人
</button>
```

3. **重启开发服务器**
   ```bash
   npm start
   ```

4. **点击按钮执行迁移**

---

### 方案3: Parse Dashboard 手动修复

如果上述方案都不work，可以在Parse Dashboard中手动修复：

**步骤**:

1. **打开Parse Dashboard**

2. **进入Project表**

3. **找到一个项目**

4. **编辑该项目**:
   - 找到 `department` 列，选择一个Department
   - 找到 `assignee` 列，选择该Department的leader
   - 保存

5. **重复步骤3-4**，直到所有项目都有负责人

---

## 🧪 验证方法

### 1. 检查数据库

在浏览器控制台执行：

```javascript
// 使用FmodeParse直接查询
const Parse = FmodeParse.with('nova');
const query = new Parse.Query('Project');
query.include(['assignee', 'department', 'department.leader']);
query.limit(5);
const projects = await query.find();

projects.forEach(p => {
  console.log('项目:', p.get('title'));
  console.log('- assignee:', p.get('assignee')?.get('name'));
  console.log('- department:', p.get('department')?.get('name'));
  console.log('- leader:', p.get('department')?.get('leader')?.get('name'));
});
```

### 2. 检查项目列表

1. 访问：`http://localhost:4200/admin/project-management`
2. 查看"负责人"列
3. **预期**：应显示组长名字，而不是"未分配"

---

## 📝 迁移脚本逻辑

```
开始迁移
  ↓
查询所有项目
  ↓
遍历每个项目
  ↓
已有assignee? → 跳过
  ↓ No
有department? → 使用其leader作为assignee
  ↓ No
查找默认项目组 → 使用其leader作为assignee
  ↓
保存项目
  ↓
下一个项目
```

---

## 🔧 迁移脚本特性

1. **安全性**：
   - 已有assignee的项目不会被覆盖
   - 支持回滚（手动删除assignee字段）

2. **智能分配**：
   - 优先使用项目的department.leader
   - 如果没有department，使用默认项目组的leader
   - 如果项目组没有leader，标记为失败

3. **详细日志**：
   - 每个项目的处理状态
   - 成功/失败统计
   - 错误原因

4. **批量处理**：
   - 一次处理最多1000个项目
   - 支持断点续传（重新运行只处理未完成的）

---

## ⚠️ 注意事项

### 执行前

1. **备份数据**：
   - 在Parse Dashboard中导出Project表数据
   - 保存备份，以防需要回滚

2. **检查项目组**：
   - 确保至少有一个项目组（Department表）
   - 确保项目组有组长（leader字段）

### 执行中

1. **不要关闭浏览器**：迁移过程中保持页面打开
2. **观察控制台**：查看进度和错误信息
3. **网络稳定**：确保网络连接正常

### 执行后

1. **验证数据**：检查几个项目的assignee字段
2. **刷新页面**：强制刷新浏览器缓存
3. **查看日志**：确认成功/失败数量

---

## 🎯 预期结果

### 迁移前

```
Project表
- project1: { title: "项目A", assignee: null, department: null }
- project2: { title: "项目B", assignee: null, department: null }
```

项目列表显示：
```
项目A    | 未分配
项目B    | 未分配
```

### 迁移后

```
Project表
- project1: { 
    title: "项目A", 
    assignee: Pointer<Profile>汪奥, 
    department: Pointer<Department>汪奥组 
  }
- project2: { 
    title: "项目B", 
    assignee: Pointer<Profile>汪奥, 
    department: Pointer<Department>汪奥组 
  }
```

项目列表显示：
```
项目A    | 汪奥
项目B    | 汪奥
```

---

## 📚 相关文件

- 迁移服务：`src/app/pages/admin/services/project-migration.service.ts`
- 项目服务：`src/app/pages/admin/services/project.service.ts`
- 分配组件：`src/modules/project/components/team-assign/team-assign.component.ts`

---

## 💡 常见问题

### Q1: 迁移后仍显示"未分配"

**A**: 
1. 强制刷新浏览器（Ctrl+Shift+R）
2. 检查浏览器缓存
3. 验证数据库中的assignee字段是否已设置

### Q2: 部分项目迁移失败

**A**: 
1. 查看控制台错误信息
2. 检查失败项目是否有可用的项目组
3. 手动在Parse Dashboard中修复

### Q3: 没有可用的项目组

**A**: 
1. 先创建项目组（Department表）
2. 设置项目组的leader字段
3. 重新运行迁移脚本

---

**准备好了吗？开始迁移吧！** 🚀


