# 浏览器控制台快速修复脚本 **使用说明**:复制下面的脚本,粘贴到浏览器控制台执行 --- ## 🚀 快速修复脚本 ### 步骤1: 打开浏览器控制台 1. 访问:`http://localhost:4200/admin/project-management` 2. 按 `F12` 打开开发者工具 3. 切换到 `Console` 标签 --- ### 步骤2: 复制并执行以下脚本 ```javascript // ================================ // 项目负责人批量更新脚本 // ================================ (async function() { console.log('🚀 开始批量更新项目负责人...'); try { // 获取Parse实例 const FmodeParse = (window as any).FmodeParse || await import('fmode-ng/parse').then(m => m.FmodeParse); const Parse = FmodeParse.with('nova'); // 获取公司ID const company = localStorage.getItem('company'); if (!company) { console.error('❌ 未找到公司ID,请先登录'); return; } console.log('✅ 公司ID:', company); // 查询所有项目 const projectQuery = new Parse.Query('Project'); projectQuery.equalTo('company', company); projectQuery.notEqualTo('isDeleted', true); projectQuery.include(['assignee', 'department', 'department.leader']); projectQuery.limit(1000); const projects = await projectQuery.find(); console.log(`📊 找到 ${projects.length} 个项目`); // 统计 let updated = 0; let skipped = 0; let failed = 0; // 遍历每个项目 for (let i = 0; i < projects.length; i++) { const project = projects[i]; const title = project.get('title') || '未命名项目'; const existingAssignee = project.get('assignee'); try { // 如果已有负责人,跳过 if (existingAssignee) { console.log(`⏭️ [${i+1}/${projects.length}] "${title}" 已有负责人: ${existingAssignee.get('name')}`); skipped++; continue; } // 检查是否有项目组 let department = project.get('department'); // 如果没有项目组,查找默认项目组 if (!department) { console.log(`🔍 [${i+1}/${projects.length}] "${title}" 没有项目组,查找默认项目组...`); const deptQuery = new Parse.Query('Department'); deptQuery.equalTo('company', company); deptQuery.equalTo('type', 'project'); deptQuery.notEqualTo('isDeleted', true); deptQuery.include('leader'); deptQuery.ascending('createdAt'); deptQuery.limit(1); department = await deptQuery.first(); } else { // 如果有项目组,确保加载了leader await department.fetch({ include: ['leader'] }); } if (!department) { console.warn(`⚠️ [${i+1}/${projects.length}] "${title}" 没有可用的项目组`); failed++; continue; } // 获取组长 const leader = department.get('leader'); if (!leader) { console.warn(`⚠️ [${i+1}/${projects.length}] "${title}" 的项目组没有组长`); failed++; continue; } // 更新项目 project.set('assignee', leader); project.set('department', department); await project.save(); updated++; console.log(`✅ [${i+1}/${projects.length}] "${title}" 已设置负责人: ${leader.get('name')}`); } catch (error) { console.error(`❌ [${i+1}/${projects.length}] 更新 "${title}" 失败:`, error); failed++; } } // 输出结果 console.log(''); console.log('='.repeat(60)); console.log('🎉 批量更新完成!'); console.log('='.repeat(60)); console.log(`📊 总计: ${projects.length} 个项目`); console.log(`✅ 成功更新: ${updated} 个`); console.log(`⏭️ 跳过(已有负责人): ${skipped} 个`); console.log(`❌ 失败: ${failed} 个`); console.log('='.repeat(60)); console.log(''); console.log('💡 请刷新页面查看结果(Ctrl+Shift+R)'); } catch (error) { console.error('❌ 执行失败:', error); } })(); ``` --- ### 步骤3: 等待执行完成 控制台会输出类似信息: ``` 🚀 开始批量更新项目负责人... ✅ 公司ID: cDL6R1hgSi 📊 找到 11 个项目 ⏭️ [1/11] "未命名案例组三期项目" 已有负责人: 汪奥 ✅ [2/11] "张家界凤凰城三期项目" 已设置负责人: 汪奥 ✅ [3/11] "日式10.6" 已设置负责人: 汪奥 ... ============================================================ 🎉 批量更新完成! ============================================================ 📊 总计: 11 个项目 ✅ 成功更新: 10 个 ⏭️ 跳过(已有负责人): 1 个 ❌ 失败: 0 个 ============================================================ 💡 请刷新页面查看结果(Ctrl+Shift+R) ``` --- ### 步骤4: 刷新页面 按 `Ctrl+Shift+R` 强制刷新页面,查看项目列表中的"负责人"列。 **预期结果**:所有项目的"负责人"列应显示组长名字(如"汪奥"),而不是"未分配"。 --- ## 📝 简化版脚本(如果上面的不work) 如果上面的脚本报错,试试这个简化版: ```javascript (async function() { const Parse = window.FmodeParse.with('nova'); const company = localStorage.getItem('company'); const query = new Parse.Query('Project'); query.equalTo('company', company); query.notEqualTo('isDeleted', true); query.doesNotExist('assignee'); query.limit(100); const projects = await query.find(); console.log('需要更新的项目数:', projects.length); // 获取第一个项目组 const deptQuery = new Parse.Query('Department'); deptQuery.equalTo('company', company); deptQuery.include('leader'); const dept = await deptQuery.first(); if (!dept) { console.error('没有找到项目组'); return; } const leader = dept.get('leader'); console.log('使用组长:', leader.get('name')); // 批量更新 for (const p of projects) { p.set('assignee', leader); p.set('department', dept); await p.save(); console.log('✅', p.get('title')); } console.log('完成!请刷新页面'); })(); ``` --- ## 🔍 验证脚本 执行更新后,运行这个脚本验证结果: ```javascript (async function() { const Parse = window.FmodeParse.with('nova'); const company = localStorage.getItem('company'); const query = new Parse.Query('Project'); query.equalTo('company', company); query.notEqualTo('isDeleted', true); query.include(['assignee', 'department']); query.limit(20); const projects = await query.find(); console.table(projects.map(p => ({ '项目名称': p.get('title'), '负责人': p.get('assignee')?.get('name') || '未分配', '项目组': p.get('department')?.get('name') || '无' }))); })(); ``` 预期输出表格: ``` ┌─────────┬────────────────────────┬──────────┬──────────┐ │ (index) │ 项目名称 │ 负责人 │ 项目组 │ ├─────────┼────────────────────────┼──────────┼──────────┤ │ 0 │ '未命名案例组三期' │ '汪奥' │ '汪奥组'│ │ 1 │ '张家界凤凰城三期' │ '汪奥' │ '汪奥组'│ │ 2 │ '日式10.6' │ '汪奥' │ '汪奥组'│ │ ... │ ... │ ... │ ... │ └─────────┴────────────────────────┴──────────┴──────────┘ ``` --- ## ⚠️ 故障排查 ### 错误1: `FmodeParse is not defined` **解决方法**: ```javascript // 先初始化FmodeParse const { FmodeParse } = await import('fmode-ng/parse'); // 然后继续执行脚本 ``` ### 错误2: `company is null` **解决方法**: ```javascript // 手动设置公司ID localStorage.setItem('company', 'cDL6R1hgSi'); // 替换为你的公司ID ``` ### 错误3: 权限错误 **解决方法**: - 确保已登录管理员账号 - 检查Parse ACL权限配置 --- ## 🎯 执行后检查 1. **控制台日志**:确认所有项目都成功更新 2. **项目列表**:刷新页面,检查"负责人"列 3. **Parse Dashboard**:查看Project表的assignee字段 4. **项目详情页**:点击任意项目,查看负责人信息 --- **现在就执行脚本,一键修复所有项目的负责人!** 🚀