将企业微信端的project-loader页面重构为功能完整的个人看板页面,支持员工自我评价、技能展示、案例作品集管理和月度统计等功能。
在 Profile.data 字段中存储以下数据:
{
data: {
// 自我评价
selfEvaluation: {
strengths: string[], // 优势标签
improvements: string[], // 待提升项标签
personalStatement: string, // 个人陈述
lastUpdated: Date // 最后更新时间
},
// 技能评分
skillRatings: [{
name: string, // 技能名称
currentScore: number, // 当前分数 (0-100)
targetScore: number, // 目标分数 (0-100)
category: string // 类别: 设计能力/沟通能力/技术能力/项目管理
}],
// 案例作品集(存储项目ID)
caseWorks: string[] // 项目ObjectId数组,最多12个
}
}
// 总项目数
const totalQuery = new Parse.Query('Project');
totalQuery.equalTo('assignee', profilePointer);
totalQuery.notEqualTo('isDeleted', true);
const totalProjects = await totalQuery.count();
// 已完成项目数
const completedQuery = new Parse.Query('Project');
completedQuery.equalTo('assignee', profilePointer);
completedQuery.equalTo('currentStage', '售后归档');
const completedProjects = await completedQuery.count();
// 本月项目数
const currentMonth = new Date();
currentMonth.setDate(1);
const monthQuery = new Parse.Query('Project');
monthQuery.equalTo('assignee', profilePointer);
monthQuery.greaterThanOrEqualTo('createdAt', currentMonth);
const currentMonthProjects = await monthQuery.count();
// 从 Profile.data.caseWorks 获取项目ID列表
const caseProjectIds = profileData.caseWorks || [];
// 查询对应的项目
const query = new Parse.Query('Project');
query.containedIn('objectId', caseProjectIds);
query.equalTo('currentStage', '售后归档');
query.notEqualTo('isDeleted', true);
query.include('contact');
query.limit(20);
const projects = await query.find();
// 查询最近6个月的项目
const sixMonthsAgo = new Date();
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
const query = new Parse.Query('Project');
query.equalTo('assignee', profilePointer);
query.greaterThanOrEqualTo('createdAt', sixMonthsAgo);
query.notEqualTo('isDeleted', true);
query.limit(1000);
const projects = await query.find();
// 按月分组统计
// 计算每月的总项目数、已完成数、收入等
// 查询所有已完成的项目供选择
const query = new Parse.Query('Project');
query.equalTo('assignee', profilePointer);
query.equalTo('currentStage', '售后归档');
query.notEqualTo('isDeleted', true);
query.include('contact');
query.descending('updatedAt');
query.limit(100);
const availableProjects = await query.find();
| 方法名 | 说明 |
|---|---|
loadPersonalBoard() |
加载个人看板所有数据 |
loadProfileData() |
加载个人资料 |
loadSkillRatings() |
加载技能评分 |
loadCaseWorks() |
加载案例作品 |
loadMonthlyStats() |
加载月度统计 |
loadSelfEvaluation() |
加载自我评价 |
calculateStatistics() |
计算统计数据 |
openEditEvaluation() |
打开编辑自我评价弹窗 |
saveEvaluation() |
保存自我评价 |
openCaseSelector() |
打开案例选择器 |
toggleProjectSelection() |
切换项目选择状态 |
saveCaseSelection() |
保存案例选择 |
saveSkillRatings() |
保存技能评分 |
transformProjectToCase() |
将项目转换为案例对象 |
getDefaultSkillRatings() |
获取默认技能评分(按角色) |
filterSkillsByCategory() |
按类别筛选技能 |
getMaxMonthlyProjects() |
获取月度最大项目数 |
updateStrengths() |
更新优势标签 |
updateImprovements() |
更新待提升项 |
触发条件: 从企微端直接访问,无群聊/联系人上下文
流程:
触发条件: 从企微群聊中打开
流程:
触发条件: 从企微联系人会话中打开
流程:
[
{ name: '空间设计', currentScore: 70, targetScore: 90, category: '设计能力' },
{ name: '色彩搭配', currentScore: 65, targetScore: 85, category: '设计能力' },
{ name: '软装搭配', currentScore: 75, targetScore: 90, category: '设计能力' },
{ name: '客户沟通', currentScore: 60, targetScore: 80, category: '沟通能力' },
{ name: '需求分析', currentScore: 65, targetScore: 85, category: '沟通能力' },
{ name: '3D建模', currentScore: 70, targetScore: 85, category: '技术能力' },
{ name: '效果图渲染', currentScore: 75, targetScore: 90, category: '技术能力' },
{ name: '项目管理', currentScore: 60, targetScore: 80, category: '项目管理' }
]
[
{ name: '客户接待', currentScore: 80, targetScore: 95, category: '沟通能力' },
{ name: '需求挖掘', currentScore: 75, targetScore: 90, category: '沟通能力' },
{ name: '订单管理', currentScore: 70, targetScore: 85, category: '项目管理' },
{ name: '售后服务', currentScore: 75, targetScore: 90, category: '沟通能力' },
{ name: '问题解决', currentScore: 65, targetScore: 85, category: '项目管理' }
]
{
strengths: ['专业扎实', '责任心强'],
improvements: ['沟通效率', '时间管理'],
personalStatement: '我是一名热爱设计的专业人士,致力于为客户提供优质的服务。',
lastUpdated: new Date()
}
所有数据保存到 Profile.data 字段:
const data = profile.get('data') || {};
// 保存自我评价
data.selfEvaluation = {
strengths: ['...'],
improvements: ['...'],
personalStatement: '...',
lastUpdated: new Date()
};
// 保存技能评分
data.skillRatings = [...];
// 保存案例作品
data.caseWorks = ['projectId1', 'projectId2', ...];
profile.set('data', data);
await profile.save();
优先级顺序:
data.referenceImages[0]data.deliverables[0].files[0]默认图片: /assets/images/default-project.jpg
let coverImage = '/assets/images/default-project.jpg';
if (data.referenceImages && data.referenceImages.length > 0) {
coverImage = data.referenceImages[0];
} else if (data.deliverables && data.deliverables.length > 0) {
const firstDeliverable = data.deliverables[0];
if (firstDeliverable.files && firstDeliverable.files.length > 0) {
coverImage = firstDeliverable.files[0];
}
}
状态管理:
activeTab: 'overview' | 'cases' | 'stats' | 'skills' = 'overview';
Promise.all() 并行加载多个数据limit 参数路由路径:/wxwork/:cid/project-loader
访问方式:
| 文件 | 说明 |
|---|---|
project-loader.component.ts |
组件逻辑(857行) |
project-loader.component.html |
模板(598行) |
project-loader.component.scss |
样式(1025行) |
✅ 所有功能已实现 ✅ 无 linter 错误 ✅ 精美的UI设计 ✅ 完整的数据对接 ✅ 响应式布局 ✅ 多场景兼容
实现日期: 2025-10-30
文档版本: v1.0
作者: AI Assistant