管理端员工信息面板中,复用的 @employee-detail-panel 组件无法显示能力问卷数据,显示"该员工尚未完成能力问卷",但实际上该员工已经完成了问卷。
1. employees.ts: viewEmployee()
↓ 调用 loadEmployeeSurvey()
2. employees.ts: loadEmployeeSurvey()
↓ 查询 Profile 和 SurveyLog 表
↓ 返回 { completed, data, profileId }
3. employees.ts: selectedEmployeeForPanel
↓ 包含 surveyCompleted 和 surveyData
4. employee-info-panel.component.html
↓ [employee]="selectedEmployeeForPanel"
5. employee-info-panel.component.ts: employeeDetailForTeamLeader getter
↓ 转换为 TeamLeaderEmployeeDetail 格式
6. <app-employee-detail-panel>
↓ [employeeDetail]="employeeDetailForTeamLeader"
7. employee-detail-panel.html
↓ @if (employeeDetail.surveyCompleted && employeeDetail.surveyData)
位置: employees.ts: loadEmployeeSurvey() (行 507-558)
检查方法:
// 打开浏览器控制台,查找以下日志
🔍 [loadEmployeeSurvey] 查找员工 徐福静 (employeeId),找到 X 个结果
预期结果: 找到 1 个结果 问题结果: 找到 0 个结果
原因:
解决方案:
// 需要确认数据库中的映射关系
// 方法1: 使用 Employee.userid (企微ID) 查询
const useridQuery = new Parse.Query('Profile');
useridQuery.equalTo('userid', emp.userid);
// 方法2: 使用 Employee.wxworkId 查询
const wxworkQuery = new Parse.Query('Profile');
wxworkQuery.equalTo('wxworkId', emp.wxworkId);
位置: employees.ts: loadEmployeeSurvey() (行 528-539)
检查方法:
// 控制台日志
📝 [loadEmployeeSurvey] 找到 X 条问卷记录
预期结果: 找到至少 1 条记录 问题结果: 找到 0 条记录
原因:
type = 'survey-profile' 不匹配(可能是其他 type 值)profile Pointer 不匹配解决方案:
// 先查询所有该用户的 SurveyLog
const allSurveyQuery = new Parse.Query('SurveyLog');
allSurveyQuery.equalTo('profile', profile.toPointer());
allSurveyQuery.descending('createdAt');
const allSurveys = await allSurveyQuery.find();
console.log('📝 所有问卷记录:', allSurveys.map(s => ({
type: s.get('type'),
answers: s.get('answers')?.length
})));
位置: employees.ts: loadEmployeeSurvey() (行 522)
检查方法:
// 控制台日志
📋 [loadEmployeeSurvey] Profile ID: xxx, surveyCompleted: false
预期结果: surveyCompleted: true
问题结果: surveyCompleted: false
原因:
surveyCompleted 字段未正确更新survey_completed 或其他)解决方案:
// 检查 Profile 的所有字段
const profile = profileResults[0];
console.log('📋 Profile 所有字段:', profile.attributes);
console.log('📋 surveyCompleted 字段值:', profile.get('surveyCompleted'));
console.log('📋 survey_completed 字段值:', profile.get('survey_completed'));
位置: employee-info-panel.component.ts: employeeDetailForTeamLeader (行 149-180)
检查方法:
// 控制台日志
✅ [employeeDetailForTeamLeader] 转换完成: {
surveyCompleted: true/false,
hasSurveyData: true/false
}
预期结果:
surveyCompleted: true
hasSurveyData: true
surveyData: { answers: [...], createdAt: Date }
问题结果:
surveyCompleted: false
hasSurveyData: false
surveyData: undefined
原因:
this.employee 中没有 surveyCompleted 或 surveyData 字段employees.ts 到 employee-info-panel 的传递中丢失解决方案:
// 在 employees.ts 中添加更详细的日志
console.log('🎯 [Employees] selectedEmployeeForPanel 完整内容:', {
...this.selectedEmployeeForPanel,
surveyCompleted: this.selectedEmployeeForPanel.surveyCompleted,
surveyData: this.selectedEmployeeForPanel.surveyData
});
按 F12 打开开发者工具,切换到 Console 标签。
点击控制台左上角的 🚫 图标,清空所有日志。
在员工列表中点击"徐福静",打开员工信息面板。
按照以下顺序查找日志:
🚀 [Employees] 开始打开员工信息面板: 徐福静 (employeeId)
🔍 [loadEmployeeSurvey] 查找员工 徐福静 (employeeId),找到 X 个结果
📋 [loadEmployeeSurvey] Profile ID: xxx, surveyCompleted: true/false
surveyCompleted: true,继续surveyCompleted: false,问题在 Profile 标记,跳到问题点 3📝 [loadEmployeeSurvey] 找到 X 条问卷记录
✅ [loadEmployeeSurvey] 问卷数据加载成功,共 X 道题
📝 [Employees] 问卷数据加载完成: {
completed: true,
answers: X
}
🎯 [Employees] 完整数据准备完成,打开面板: {
surveyData: '✅'
}
surveyData: '✅',继续surveyData: '❌',数据未正确传递✅ [employeeDetailForTeamLeader] 转换完成: {
surveyCompleted: true,
hasSurveyData: true
}
📦 [employeeDetailForTeamLeader] 完整数据结构: {
employee: {...},
result: {
surveyCompleted: true,
surveyData: {...}
}
}
result.surveyData 是否包含 answers 数组在 employees.ts 的 loadEmployeeSurvey 方法中添加更多日志:
// 在 line 507 附近添加
console.log('🔍 [loadEmployeeSurvey] 查询参数:', {
employeeId,
employeeName,
useridQuery: emp.userid,
wxworkId: emp.wxworkId
});
// 在 line 514 附近添加
if (profileResults.length > 0) {
const profile = profileResults[0];
console.log('📋 [loadEmployeeSurvey] Profile 完整信息:', {
id: profile.id,
realname: profile.get('realname'),
name: profile.get('name'),
surveyCompleted: profile.get('surveyCompleted'),
allAttributes: profile.attributes
});
}
// 在 line 528 附近添加
console.log('📝 [loadEmployeeSurvey] SurveyLog 查询参数:', {
profileId: profile.id,
profilePointer: profile.toPointer(),
type: 'survey-profile'
});
// 在 line 531 附近添加
console.log('📝 [loadEmployeeSurvey] SurveyLog 查询结果:', {
count: surveyResults.length,
surveys: surveyResults.map(s => ({
id: s.id,
type: s.get('type'),
answersCount: s.get('answers')?.length,
createdAt: s.get('createdAt')
}))
});
如果 type = 'survey-profile' 查询不到,尝试其他 type:
// 在 loadEmployeeSurvey 方法中,line 528 附近
if (surveyCompleted) {
// 先尝试 'survey-profile' type
let surveyQuery = new Parse.Query('SurveyLog');
surveyQuery.equalTo('profile', profile.toPointer());
surveyQuery.equalTo('type', 'survey-profile');
surveyQuery.descending('createdAt');
surveyQuery.limit(1);
let surveyResults = await surveyQuery.find();
console.log(`📝 [loadEmployeeSurvey] 找到 'survey-profile' 类型: ${surveyResults.length} 条`);
// 如果找不到,尝试不限制 type
if (surveyResults.length === 0) {
console.warn(`⚠️ [loadEmployeySurvey] 'survey-profile' 类型未找到,尝试查询所有类型`);
surveyQuery = new Parse.Query('SurveyLog');
surveyQuery.equalTo('profile', profile.toPointer());
surveyQuery.descending('createdAt');
surveyQuery.limit(1);
surveyResults = await surveyQuery.find();
console.log(`📝 [loadEmployeeSurvey] 找到所有类型: ${surveyResults.length} 条`);
}
if (surveyResults.length > 0) {
const survey = surveyResults[0];
const surveyData = {
answers: survey.get('answers') || [],
createdAt: survey.get('createdAt'),
updatedAt: survey.get('updatedAt')
};
console.log(`✅ [loadEmployeeSurvey] 问卷数据加载成功,type: ${survey.get('type')}, 共 ${surveyData.answers.length} 道题`);
return {
completed: true,
data: surveyData,
profileId
};
}
}
组长端的 dashboard.ts 中已经有正确的查询逻辑(line 3184-3237),可以完全复用:
// 在 employees.ts 中,复制组长端的查询逻辑
private async loadEmployeeSurvey(employeeId: string, employeeName: string): Promise<{ completed: boolean; data: any; profileId: string }> {
try {
const Parse = await import('fmode-ng/parse').then(m => m.FmodeParse.with('nova'));
// 💡 完全复用组长端的查询逻辑
// 通过员工名字查找Profile(同时查询 realname 和 name 字段)
const realnameQuery = new Parse.Query('Profile');
realnameQuery.equalTo('realname', employeeName);
const nameQuery = new Parse.Query('Profile');
nameQuery.equalTo('name', employeeName);
// 使用 or 查询
const profileQuery = Parse.Query.or(realnameQuery, nameQuery);
profileQuery.limit(1);
const profileResults = await profileQuery.find();
console.log(`🔍 查找员工 ${employeeName},找到 ${profileResults.length} 个结果`);
if (profileResults.length > 0) {
const profile = profileResults[0];
const profileId = profile.id;
const surveyCompleted = profile.get('surveyCompleted') || false;
console.log(`📋 Profile ID: ${profileId}, surveyCompleted: ${surveyCompleted}`);
// 如果已完成问卷,加载问卷答案
if (surveyCompleted) {
const surveyQuery = new Parse.Query('SurveyLog');
surveyQuery.equalTo('profile', profile.toPointer());
surveyQuery.equalTo('type', 'survey-profile');
surveyQuery.descending('createdAt');
surveyQuery.limit(1);
const surveyResults = await surveyQuery.find();
console.log(`📝 找到 ${surveyResults.length} 条问卷记录`);
if (surveyResults.length > 0) {
const survey = surveyResults[0];
const surveyData = {
answers: survey.get('answers') || [],
createdAt: survey.get('createdAt'),
updatedAt: survey.get('updatedAt')
};
console.log(`✅ 加载问卷数据成功,共 ${surveyData.answers.length} 道题`);
return {
completed: true,
data: surveyData,
profileId
};
}
}
return {
completed: false,
data: null,
profileId
};
} else {
console.warn(`⚠️ 未找到员工 ${employeeName} 的 Profile`);
return {
completed: false,
data: null,
profileId: ''
};
}
} catch (error) {
console.error(`❌ 加载员工 ${employeeName} 问卷数据失败:`, error);
return {
completed: false,
data: null,
profileId: ''
};
}
}
在提交问题或进行修复前,请完成以下检查:
surveyCompleted 字段为 trueanswers 数组有数据selectedEmployeeForPanel.surveyData 有值employeeDetailForTeamLeader.surveyData 有值@if (employeeDetail.surveyCompleted && employeeDetail.surveyData) 被满足修复后,在控制台应该看到完整的数据链路:
🚀 [Employees] 开始打开员工信息面板: 徐福静
🔄 [Employees] 预加载员工数据...
✅ [Employees] 项目数据加载完成: { currentProjects: 3, ... }
📅 [Employees] 日历数据生成完成: { days: 42, 有项目的天数: 15 }
🔍 [loadEmployeeSurvey] 查找员工 徐福静,找到 1 个结果
📋 [loadEmployeeSurvey] Profile ID: xxx, surveyCompleted: true
📝 [loadEmployeeSurvey] 找到 1 条问卷记录
✅ [loadEmployeeSurvey] 问卷数据加载成功,共 25 道题 // ✅ 关键
📝 [Employees] 问卷数据加载完成: { completed: true, answers: 25 }
🎯 [Employees] 完整数据准备完成,打开面板: { surveyData: '✅' }
✅ [Employees] 面板已显示
🔍 [employeeDetailForTeamLeader] 开始转换
✅ [employeeDetailForTeamLeader] 转换完成: {
surveyCompleted: true, // ✅ 关键
hasSurveyData: true // ✅ 关键
}
然后在页面上应该能看到:
文档版本: v1.0 创建日期: 2025-11-10 状态: 调试指南