BATCH_UPDATE_DELIVERY_STAGE.md 9.4 KB

批量更新交付执行阶段 - 统一显示脚本

📋 需求说明

将项目管理页面中所有当前阶段为"白膜"、"软装"、"渲染"、"后期"的项目统一更新为"交付执行",状态自动同步为"进行中"。


🔍 问题分析

当前情况

// 项目管理页面显示
{
  当前阶段: "白膜" / "软装" / "渲染" / "后期",
  状态: "进行中" (通过 getProjectStatusByStage 映射)
}

// 数据库存储
{
  currentStage: "白膜" / "软装" / "渲染" / "后期"
}

目标状态

// 项目管理页面显示
{
  当前阶段: "交付执行",
  状态: "进行中"
}

// 数据库存储
{
  currentStage: "交付执行",
  data: {
    deliverySubStage: "白膜" / "软装" / "渲染" / "后期"  // 保留子阶段信息
  }
}

🚀 批量更新脚本

方案1:浏览器控制台执行(推荐)

步骤

  1. 打开项目管理页面
  2. 按 F12 打开浏览器控制台
  3. 复制并执行以下脚本

    // 批量更新交付执行阶段项目
    async function batchUpdateDeliveryStage() {
    const Parse = window.Parse;
      
    console.log('🔍 开始查询需要更新的项目...');
      
    // 查询所有处于子阶段的项目
    const query = new Parse.Query('Project');
    query.containedIn('currentStage', ['白膜', '软装', '渲染', '后期', '白模', '建模']);
    query.limit(1000); // 限制最多1000个
      
    try {
    const projects = await query.find();
    console.log(`📊 找到 ${projects.length} 个需要更新的项目`);
        
    if (projects.length === 0) {
      console.log('✅ 没有需要更新的项目');
      return;
    }
        
    // 显示项目列表
    console.table(projects.map(p => ({
      项目名称: p.get('title'),
      当前阶段: p.get('currentStage'),
      客户: p.get('contact')?.get('name') || p.get('customer')?.get('name') || '未知'
    })));
        
    // 确认是否继续
    const confirmed = confirm(`找到 ${projects.length} 个项目需要更新。\n\n是否继续将它们的阶段统一为"交付执行"?`);
        
    if (!confirmed) {
      console.log('❌ 用户取消更新');
      return;
    }
        
    console.log('🔄 开始批量更新...');
        
    let successCount = 0;
    let errorCount = 0;
        
    // 批量更新
    for (const project of projects) {
      try {
        const currentStage = project.get('currentStage');
        const data = project.get('data') || {};
            
        // 保存子阶段信息
        data.deliverySubStage = currentStage;
            
        // 统一为"交付执行"
        project.set('currentStage', '交付执行');
        project.set('data', data);
            
        await project.save();
            
        successCount++;
        console.log(`✅ [${successCount}/${projects.length}] ${project.get('title')}: "${currentStage}" → "交付执行"`);
      } catch (error) {
        errorCount++;
        console.error(`❌ 更新失败: ${project.get('title')}`, error);
      }
    }
        
    console.log('\n📊 更新完成统计:');
    console.log(`✅ 成功: ${successCount} 个`);
    console.log(`❌ 失败: ${errorCount} 个`);
    console.log(`📌 总计: ${projects.length} 个`);
        
    alert(`批量更新完成!\n\n成功: ${successCount} 个\n失败: ${errorCount} 个`);
        
    // 刷新页面
    if (successCount > 0) {
      console.log('🔄 3秒后自动刷新页面...');
      setTimeout(() => {
        window.location.reload();
      }, 3000);
    }
        
    } catch (error) {
    console.error('❌ 查询失败:', error);
    alert('查询失败,请检查网络连接');
    }
    }
    
    // 执行更新
    batchUpdateDeliveryStage();
    

方案2:分步执行(更安全)

如果想先查看再更新,可以分两步执行:

步骤1:查看需要更新的项目

const Parse = window.Parse;
const query = new Parse.Query('Project');
query.containedIn('currentStage', ['白膜', '软装', '渲染', '后期', '白模', '建模']);
query.limit(1000);

const projects = await query.find();
console.log(`找到 ${projects.length} 个项目`);

// 显示详细列表
console.table(projects.map(p => ({
  ID: p.id,
  项目名称: p.get('title'),
  当前阶段: p.get('currentStage'),
  状态: p.get('status'),
  客户: p.get('contact')?.get('name') || '未知',
  更新时间: p.get('updatedAt')
})));

步骤2:确认后执行更新

// 批量更新(使用上面查询到的 projects)
let successCount = 0;
for (const project of projects) {
  const currentStage = project.get('currentStage');
  const data = project.get('data') || {};
  
  data.deliverySubStage = currentStage;
  project.set('currentStage', '交付执行');
  project.set('data', data);
  
  try {
    await project.save();
    successCount++;
    console.log(`✅ [${successCount}] ${project.get('title')}: "${currentStage}" → "交付执行"`);
  } catch (e) {
    console.error(`❌ ${project.get('title')} 更新失败:`, e);
  }
}

console.log(`✅ 完成!成功更新 ${successCount}/${projects.length} 个项目`);

方案3:更新单个项目(测试用)

如果想先测试一个项目:

const Parse = window.Parse;

// 替换为实际项目ID
const projectId = '你的项目ID';

const query = new Parse.Query('Project');
query.equalTo('objectId', projectId);
const project = await query.first();

if (project) {
  const currentStage = project.get('currentStage');
  console.log('当前阶段:', currentStage);
  
  const data = project.get('data') || {};
  data.deliverySubStage = currentStage;
  
  project.set('currentStage', '交付执行');
  project.set('data', data);
  
  await project.save();
  
  console.log('✅ 更新成功:', {
    项目: project.get('title'),
    旧阶段: currentStage,
    新阶段: project.get('currentStage'),
    子阶段: project.get('data').deliverySubStage
  });
} else {
  console.log('❌ 未找到项目');
}

🎯 更新后的效果

1. 数据库变化

// 更新前
{
  objectId: "APwK78jmrh",
  title: "张家界鼎盛项目",
  currentStage: "软装",  // ❌ 子阶段
  data: {}
}

// 更新后
{
  objectId: "APwK78jmrh",
  title: "张家界鼎盛项目",
  currentStage: "交付执行",  // ✅ 统一
  data: {
    deliverySubStage: "软装"  // ✅ 子阶段保留
  }
}

2. 项目管理页面显示

更新前:
- 当前阶段:软装 / 白膜 / 渲染 / 后期
- 状态:进行中

更新后:
- 当前阶段:交付执行 ✅
- 状态:进行中 ✅

3. 项目详情页面显示

顶部进度条:交付执行 ✅
底部卡片:交付执行 ✅
内部工作流:白膜/软装/渲染/后期(保留)✅

🔍 验证方法

1. 验证更新是否成功

const Parse = window.Parse;

// 查询所有交付执行阶段的项目
const query = new Parse.Query('Project');
query.equalTo('currentStage', '交付执行');
const projects = await query.find();

console.log(`✅ 共有 ${projects.length} 个项目处于"交付执行"阶段`);

// 查看子阶段分布
const subStages = projects.map(p => p.get('data')?.deliverySubStage).filter(Boolean);
console.log('子阶段分布:', {
  白膜: subStages.filter(s => s === '白膜').length,
  软装: subStages.filter(s => s === '软装').length,
  渲染: subStages.filter(s => s === '渲染').length,
  后期: subStages.filter(s => s === '后期').length
});

2. 检查是否还有未更新的项目

const Parse = window.Parse;
const query = new Parse.Query('Project');
query.containedIn('currentStage', ['白膜', '软装', '渲染', '后期', '白模', '建模']);
const remaining = await query.find();

if (remaining.length > 0) {
  console.warn(`⚠️ 还有 ${remaining.length} 个项目未更新`);
  console.table(remaining.map(p => ({
    项目: p.get('title'),
    阶段: p.get('currentStage')
  })));
} else {
  console.log('✅ 所有项目都已更新');
}

3. 刷新项目管理页面

更新完成后,刷新项目管理页面,检查:

  • ✅ 当前阶段列显示"交付执行"
  • ✅ 状态列显示"进行中"

⚠️ 注意事项

  1. 备份重要:虽然脚本会保留子阶段信息,但建议先在测试环境测试
  2. 网络连接:确保网络连接稳定,避免更新中断
  3. 权限检查:确保当前账号有修改项目的权限
  4. 并发限制:脚本使用顺序更新,避免并发冲突
  5. 子阶段保留:原有的子阶段信息会保存到 data.deliverySubStage

🔄 回滚方法(如需要)

如果需要恢复某个项目:

const Parse = window.Parse;
const projectId = '项目ID';

const query = new Parse.Query('Project');
const project = await query.get(projectId);

const data = project.get('data') || {};
const originalSubStage = data.deliverySubStage;  // 获取原子阶段

if (originalSubStage) {
  project.set('currentStage', originalSubStage);  // 恢复为子阶段
  delete data.deliverySubStage;
  project.set('data', data);
  await project.save();
  
  console.log(`✅ 已恢复项目 "${project.get('title')}" 的阶段为: ${originalSubStage}`);
}

✅ 执行检查清单

  • 已在浏览器打开项目管理页面
  • 已按 F12 打开控制台
  • 已复制完整的批量更新脚本
  • 已确认要更新的项目数量
  • 点击确认执行更新
  • 等待更新完成
  • 刷新页面验证结果
  • 检查项目详情页面显示

准备好后,复制"方案1"的脚本到浏览器控制台执行即可! 🚀