# 数据加载与甘特图显示问题修复 **日期**: 2025-10-22 11:00 **问题**: 控制台报错 `TypeError: deadline.getTime is not a function`,甘特图无法显示真实数据 --- ## 问题分析 ### 1. 主要错误 ``` TypeError: deadline.getTime is not a function at DesignerService.transformProject (designer.service.ts:219:42) ``` ### 2. 根本原因 `transformProject` 中直接调用 `deadline.getTime()`,但未验证 `deadline` 是否为 Date 对象。Parse 查询可能返回: - Date 对象(正常) - null/undefined(字段不存在) - 字符串(类型不匹配) ### 3. 甘特图显示说明 **甘特图设计是正确的**: - ✅ Y轴显示**设计师名字**(按负载排序) - ✅ X轴显示**时间轴**(周/月视图) - ✅ 条形图显示**每个设计师负责的项目及其时间线** - ✅ 颜色标识**项目紧急度**(红色=高,橙色=中,绿色=低) - ✅ 背景色标识**设计师负载状态**(绿色=空闲,红色=超负荷) 这就是"设计师排版时间轴"的正确呈现方式。用户看到的"项目数据"是指条形图中的项目名称和截止日期,这是**预期行为**。 --- ## 修复内容 ### 1. 修复 Date 类型处理(designer.service.ts) #### calculateProjectWeight (Line 164-188) ```typescript // 修复前 const deadline = project.get?.('deadline') || project.deadline; const daysLeft = deadline ? Math.ceil((deadline.getTime() - now.getTime()) / ...) : 30; // 修复后 const deadlineRaw = project.get?.('deadline') || project.deadline; const deadline = deadlineRaw instanceof Date ? deadlineRaw : (deadlineRaw ? new Date(deadlineRaw) : null); const daysLeft = deadline ? Math.ceil((deadline.getTime() - now.getTime()) / ...) : 30; ``` #### transformProject (Line 216-221) ```typescript // 修复前 const deadline = project.get('deadline') || new Date(); // 修复后 const deadlineRaw = project.get('deadline'); const deadline = deadlineRaw instanceof Date ? deadlineRaw : (deadlineRaw ? new Date(deadlineRaw) : new Date()); ``` ### 2. 添加调试日志 **constructor (Line 36-40)**: ```typescript constructor() { this.cid = localStorage.getItem('company') || ''; console.log('🏢 DesignerService初始化,当前公司ID:', this.cid || '(未设置)'); this.initParse(); } ``` **getProjects (Line 193-227)**: ```typescript async getProjects(): Promise { const Parse = await this.ensureParse(); if (!Parse) { console.error('❌ Parse未初始化,无法查询项目'); return []; } if (!this.cid) { console.error('❌ 未找到公司ID(localStorage的company字段为空),无法查询项目'); return []; } console.log('🔍 开始查询项目,company:', this.cid); const query = new Parse.Query('Project'); // ... 查询逻辑 console.log(`✅ Parse查询成功,找到 ${projects.length} 个项目`); if (projects.length === 0) { console.warn('⚠️ 数据库中没有符合条件的项目数据'); console.warn('💡 提示:请确保Project表中有数据,且company字段=', this.cid); } return projects.map((p: any) => this.transformProject(p)); } ``` --- ## 验证步骤 ### 1. 检查控制台日志 刷新页面后,应该看到以下日志: ``` 🏢 DesignerService初始化,当前公司ID: <你的company ID> ✅ DesignerService: FmodeParse 初始化成功 🔍 开始查询项目,company: <你的company ID> ✅ Parse查询成功,找到 X 个项目 ``` ### 2. 如果看到"未找到公司ID" 说明 `localStorage.getItem('company')` 为空,需要: - 确认是否已登录 - 检查登录流程是否正确设置了 `localStorage.company` ### 3. 如果看到"找到 0 个项目" 说明数据库中没有符合条件的Project数据,需要: - 确认Project表中有数据 - 确认Project.company字段与当前company ID匹配 - 确认Project.isDeleted字段不为true ### 4. 检查甘特图显示 如果有真实数据,甘特图应该显示: - Y轴:设计师名字列表 - X轴:时间轴(默认显示"周"视图,未来7天) - 条形图:每个设计师负责的项目 - 颜色:红色(高紧急度)、橙色(中)、绿色(低) - 背景:绿色背景=设计师空闲可接单,红色背景=超负荷 --- ## 数据准备 ### 确保Project表有测试数据 ```javascript // 在Parse Dashboard或云函数中执行: const Project = Parse.Object.extend("Project"); const project = new Project(); project.set("title", "测试项目-现代客厅设计"); project.set("company", "<你的company objectId>"); project.set("status", "进行中"); project.set("currentStage", "modeling"); project.set("deadline", new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)); // 7天后 // 可选:关联设计师 const Profile = Parse.Object.extend("Profile"); const designer = Profile.createWithoutData("<设计师objectId>"); project.set("assignee", designer); // 可选:设置扩展数据 project.set("data", { projectType: "soft", // soft=软装, hard=硬装 urgency: "high", // high/medium/low style: "现代简约" }); await project.save(); ``` ### 确保Profile表有设计师数据 ```javascript const Profile = Parse.Object.extend("Profile"); const profile = new Profile(); profile.set("name", "张三"); profile.set("company", "<你的company objectId>"); profile.set("roleName", "组员"); // 重要:必须是"组员"角色 profile.set("data", { tags: { expertise: { styles: ["现代简约", "北欧风格"], skills: ["建模", "渲染"], spaceTypes: ["客厅", "卧室"] }, capacity: { weeklyProjects: 3, maxConcurrent: 5, avgDaysPerProject: 10 }, emergency: { willing: true, premium: 20, maxPerWeek: 2 }, history: { totalProjects: 15, completionRate: 90, avgRating: 4.5, onTimeRate: 85, excellentCount: 5 }, portfolio: [] } }); await profile.save(); ``` --- ## 下一步 如果数据库中确实没有数据,系统会**自动使用模拟数据**(fallback机制),甘特图仍然可以正常显示和测试。 等数据准备好后,刷新页面即可看到真实数据。 --- ## 相关文件 - `src/app/pages/team-leader/services/designer.service.ts` - 修复Date处理,添加调试日志 - `src/app/pages/team-leader/dashboard/dashboard.ts` - 调用数据服务 - `rules/schemas.md` - YSS项目的数据表结构