PERSONAL-BOARD-IMPLEMENTATION.md 11 KB

个人看板功能实现文档

📋 概述

将企业微信端的project-loader页面重构为功能完整的个人看板页面,支持员工自我评价、技能展示、案例作品集管理和月度统计等功能。

✨ 核心功能

1. 个人信息展示

  • ✅ 头像和基本信息
  • ✅ 角色显示
  • ✅ 实时统计数据(总项目数、已完成、本月项目、案例数量)

2. 自我评价系统

  • ✅ 个人陈述编辑
  • ✅ 优势标签管理
  • ✅ 待提升项标签管理
  • ✅ 最后更新时间记录
  • ✅ 实时编辑和保存

3. 技能评分系统

  • ✅ 按类别分组展示(设计能力、沟通能力、技术能力、项目管理)
  • ✅ 当前分数 vs 目标分数
  • ✅ 可视化进度条
  • ✅ 分数颜色区分(高/中/低)
  • ✅ 滑块编辑器

4. 案例作品集

  • ✅ 从已完成项目中选择案例
  • ✅ 最多12个案例展示
  • ✅ 案例卡片(封面图、标题、客户、标签、价格、完成日期)
  • ✅ 网格布局
  • ✅ 案例选择器弹窗

5. 月度统计

  • ✅ 最近6个月项目数据
  • ✅ 月度项目数、已完成数、收入统计
  • ✅ 柱状图可视化
  • ✅ 完成率、月均项目计算

6. 多场景兼容

  • ✅ 保留原有群聊场景(创建项目)
  • ✅ 保留原有联系人场景(跳转客户画像)
  • ✅ 新增个人看板场景(默认)

🗂️ 数据结构

Profile 数据扩展

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个
  }
}

📊 数据查询逻辑

1. 个人信息统计

// 总项目数
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();

2. 案例作品查询

// 从 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();

3. 月度统计

// 查询最近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();

// 按月分组统计
// 计算每月的总项目数、已完成数、收入等

4. 可选项目列表(案例选择器)

// 查询所有已完成的项目供选择
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();

🎨 UI 设计特点

1. 现代化设计

  • 渐变色系: 紫色主题 (#667eea → #764ba2)
  • 卡片式布局: 圆角、阴影、悬停效果
  • 流畅动画: 淡入、滑动、缩放等过渡效果

2. 响应式适配

  • 桌面端: 最大宽度800px,双列/多列网格
  • 平板端: 自适应网格
  • 移动端: 单列布局,底部弹窗

3. 组件样式

  • 统计卡片: 渐变图标 + 数字展示
  • 选项卡: iOS风格,活动状态高亮
  • 技能条: 进度条 + 分数徽章
  • 案例卡: 图片封面 + 信息叠加
  • 柱状图: 响应式高度,顶部标签

🔧 核心方法

TypeScript 方法

方法名 说明
loadPersonalBoard() 加载个人看板所有数据
loadProfileData() 加载个人资料
loadSkillRatings() 加载技能评分
loadCaseWorks() 加载案例作品
loadMonthlyStats() 加载月度统计
loadSelfEvaluation() 加载自我评价
calculateStatistics() 计算统计数据
openEditEvaluation() 打开编辑自我评价弹窗
saveEvaluation() 保存自我评价
openCaseSelector() 打开案例选择器
toggleProjectSelection() 切换项目选择状态
saveCaseSelection() 保存案例选择
saveSkillRatings() 保存技能评分
transformProjectToCase() 将项目转换为案例对象
getDefaultSkillRatings() 获取默认技能评分(按角色)
filterSkillsByCategory() 按类别筛选技能
getMaxMonthlyProjects() 获取月度最大项目数
updateStrengths() 更新优势标签
updateImprovements() 更新待提升项

📱 使用场景

场景1: 个人看板(默认)

触发条件: 从企微端直接访问,无群聊/联系人上下文

流程:

  1. 初始化SDK
  2. 获取当前用户Profile
  3. 加载个人看板数据
  4. 显示概览、技能、案例、统计四个选项卡

场景2: 群聊场景(保留)

触发条件: 从企微群聊中打开

流程:

  1. 检测群聊上下文
  2. 查询群聊关联的项目
  3. 如有项目 → 跳转项目详情
  4. 如无项目 → 显示创建项目引导

场景3: 联系人场景(保留)

触发条件: 从企微联系人会话中打开

流程:

  1. 检测联系人上下文
  2. 同步联系人信息
  3. 跳转客户画像页面

🎯 默认值设计

设计师/组员默认技能

[
  { 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();

📸 案例图片获取策略

优先级顺序:

  1. 参考图片: data.referenceImages[0]
  2. 交付物图片: data.deliverables[0].files[0]
  3. 默认图片: /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';

📝 表单验证

自我评价

  • 个人陈述: 无限制
  • 优势/待提升: 逗号分隔,自动去除空格

技能评分

  • 分数范围: 0-100
  • 步长: 5

案例选择

  • 最大数量: 12个
  • 条件: 必须是已完成项目(售后归档)

🚀 性能优化

  1. 并行加载: 使用 Promise.all() 并行加载多个数据
  2. 限制查询: 合理设置 limit 参数
  3. 缓存数据: Profile 数据存储在内存
  4. 懒加载: 案例选择器打开时才加载可选项目

🔒 权限控制

  • 查看: 所有员工可查看自己的看板
  • 编辑: 仅本人可编辑自己的数据
  • 案例: 只能从自己负责的已完成项目中选择

🌐 路由配置

路由路径:/wxwork/:cid/project-loader

访问方式:

  • 企微端自定义菜单
  • 企微应用首页
  • 群聊/联系人会话(自动识别场景)

📦 文件清单

文件 说明
project-loader.component.ts 组件逻辑(857行)
project-loader.component.html 模板(598行)
project-loader.component.scss 样式(1025行)

✅ 测试要点

  • 个人看板数据加载正常
  • 自我评价编辑和保存
  • 技能评分编辑和保存
  • 案例选择和保存(最多12个)
  • 月度统计计算正确
  • 柱状图渲染正常
  • 响应式适配(桌面/平板/移动)
  • 群聊场景兼容(创建项目)
  • 联系人场景兼容(跳转客户画像)
  • 默认值生成正确(按角色)

🎉 完成状态

✅ 所有功能已实现 ✅ 无 linter 错误 ✅ 精美的UI设计 ✅ 完整的数据对接 ✅ 响应式布局 ✅ 多场景兼容


实现日期: 2025-10-30
文档版本: v1.0
作者: AI Assistant