|  | @@ -16,6 +16,46 @@ interface WxworkCurrentChat {
 | 
											
												
													
														|  |    [key: string]: any;
 |  |    [key: string]: any;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// 个人技能评分
 | 
											
												
													
														|  | 
 |  | +interface SkillRating {
 | 
											
												
													
														|  | 
 |  | +  name: string;
 | 
											
												
													
														|  | 
 |  | +  currentScore: number;
 | 
											
												
													
														|  | 
 |  | +  targetScore: number;
 | 
											
												
													
														|  | 
 |  | +  category: '设计能力' | '沟通能力' | '技术能力' | '项目管理';
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +// 案例作品
 | 
											
												
													
														|  | 
 |  | +interface CaseWork {
 | 
											
												
													
														|  | 
 |  | +  id: string;
 | 
											
												
													
														|  | 
 |  | +  projectId: string;
 | 
											
												
													
														|  | 
 |  | +  projectTitle: string;
 | 
											
												
													
														|  | 
 |  | +  coverImage: string;
 | 
											
												
													
														|  | 
 |  | +  description: string;
 | 
											
												
													
														|  | 
 |  | +  tags: string[];
 | 
											
												
													
														|  | 
 |  | +  completionDate: Date;
 | 
											
												
													
														|  | 
 |  | +  customerName: string;
 | 
											
												
													
														|  | 
 |  | +  status: string;
 | 
											
												
													
														|  | 
 |  | +  totalPrice?: number;
 | 
											
												
													
														|  | 
 |  | +  roomType?: string;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +// 月度统计
 | 
											
												
													
														|  | 
 |  | +interface MonthlyStats {
 | 
											
												
													
														|  | 
 |  | +  month: string;
 | 
											
												
													
														|  | 
 |  | +  totalProjects: number;
 | 
											
												
													
														|  | 
 |  | +  completedProjects: number;
 | 
											
												
													
														|  | 
 |  | +  revenue: number;
 | 
											
												
													
														|  | 
 |  | +  avgScore: number;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +// 自我评价
 | 
											
												
													
														|  | 
 |  | +interface SelfEvaluation {
 | 
											
												
													
														|  | 
 |  | +  strengths: string[];        // 优势
 | 
											
												
													
														|  | 
 |  | +  improvements: string[];     // 待提升
 | 
											
												
													
														|  | 
 |  | +  personalStatement: string;  // 个人陈述
 | 
											
												
													
														|  | 
 |  | +  lastUpdated: Date;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  function wxdebug(...params:any[]){
 |  |  function wxdebug(...params:any[]){
 | 
											
												
													
														|  |    console.log(params)
 |  |    console.log(params)
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -23,18 +63,16 @@ function wxdebug(...params:any[]){
 | 
											
												
													
														|  |  const Parse = FmodeParse.with('nova');
 |  |  const Parse = FmodeParse.with('nova');
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  /**
 |  |  /**
 | 
											
												
													
														|  | - * 项目预加载页面
 |  | 
 | 
											
												
													
														|  | 
 |  | + * 个人看板页面(重构自项目预加载页面)
 | 
											
												
													
														|  |   *
 |  |   *
 | 
											
												
													
														|  |   * 功能:
 |  |   * 功能:
 | 
											
												
													
														|  | - * 1. 从企微会话获取上下文(群聊或联系人)
 |  | 
 | 
											
												
													
														|  | - * 2. 获取当前登录用户(Profile)
 |  | 
 | 
											
												
													
														|  | - * 3. 根据场景跳转到对应页面
 |  | 
 | 
											
												
													
														|  | - *    - 群聊 → 项目详情 或 创建项目引导
 |  | 
 | 
											
												
													
														|  | - *    - 联系人 → 客户画像
 |  | 
 | 
											
												
													
														|  | 
 |  | + * 1. 展示个人信息和自我评价
 | 
											
												
													
														|  | 
 |  | + * 2. 技能评分和发展目标
 | 
											
												
													
														|  | 
 |  | + * 3. 案例作品集(从完成项目选择)
 | 
											
												
													
														|  | 
 |  | + * 4. 月度接单量统计
 | 
											
												
													
														|  | 
 |  | + * 5. 支持编辑个人资料和案例
 | 
											
												
													
														|  |   *
 |  |   *
 | 
											
												
													
														|  |   * 路由:/wxwork/:cid/project-loader
 |  |   * 路由:/wxwork/:cid/project-loader
 | 
											
												
													
														|  | - *
 |  | 
 | 
											
												
													
														|  | - * 参考实现:nova-admin/projects/nova-crm/src/modules/chat/page-chat-context
 |  | 
 | 
											
												
													
														|  |   */
 |  |   */
 | 
											
												
													
														|  |  @Component({
 |  |  @Component({
 | 
											
												
													
														|  |    selector: 'app-project-loader',
 |  |    selector: 'app-project-loader',
 | 
											
										
											
												
													
														|  | @@ -58,20 +96,46 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |    wecorp: WxworkCorp | null = null;
 |  |    wecorp: WxworkCorp | null = null;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    // 上下文数据
 |  |    // 上下文数据
 | 
											
												
													
														|  | -  currentUser: FmodeObject | null = null;   // Profile 或 UserSocial
 |  | 
 | 
											
												
													
														|  | 
 |  | +  currentUser: FmodeObject | null = null;   // Profile
 | 
											
												
													
														|  |    currentChat: WxworkCurrentChat | null = null;
 |  |    currentChat: WxworkCurrentChat | null = null;
 | 
											
												
													
														|  | -  chatType: 'group' | 'contact' | 'none' = 'none';
 |  | 
 | 
											
												
													
														|  | 
 |  | +  chatType: 'group' | 'contact' | 'personal' = 'personal';
 | 
											
												
													
														|  |    groupChat: FmodeObject | null = null;     // GroupChat
 |  |    groupChat: FmodeObject | null = null;     // GroupChat
 | 
											
												
													
														|  |    contact: FmodeObject | null = null;       // ContactInfo
 |  |    contact: FmodeObject | null = null;       // ContactInfo
 | 
											
												
													
														|  |    project: FmodeObject | null = null;       // Project
 |  |    project: FmodeObject | null = null;       // Project
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  // 创建项目引导
 |  | 
 | 
											
												
													
														|  | 
 |  | +  // 个人看板数据
 | 
											
												
													
														|  | 
 |  | +  skillRatings: SkillRating[] = [];
 | 
											
												
													
														|  | 
 |  | +  caseWorks: CaseWork[] = [];
 | 
											
												
													
														|  | 
 |  | +  monthlyStats: MonthlyStats[] = [];
 | 
											
												
													
														|  | 
 |  | +  selfEvaluation: SelfEvaluation = {
 | 
											
												
													
														|  | 
 |  | +    strengths: [],
 | 
											
												
													
														|  | 
 |  | +    improvements: [],
 | 
											
												
													
														|  | 
 |  | +    personalStatement: '',
 | 
											
												
													
														|  | 
 |  | +    lastUpdated: new Date()
 | 
											
												
													
														|  | 
 |  | +  };
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  // UI状态
 | 
											
												
													
														|  | 
 |  | +  activeTab: 'overview' | 'cases' | 'stats' | 'skills' = 'overview';
 | 
											
												
													
														|  | 
 |  | +  showEditEvaluation: boolean = false;
 | 
											
												
													
														|  | 
 |  | +  showCaseSelector: boolean = false;
 | 
											
												
													
														|  | 
 |  | +  showSkillEditor: boolean = false;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  // 编辑状态
 | 
											
												
													
														|  | 
 |  | +  editingEvaluation: SelfEvaluation | null = null;
 | 
											
												
													
														|  | 
 |  | +  availableProjects: FmodeObject[] = [];
 | 
											
												
													
														|  | 
 |  | +  selectedProjectIds: string[] = [];
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  // 统计数据
 | 
											
												
													
														|  | 
 |  | +  totalProjects: number = 0;
 | 
											
												
													
														|  | 
 |  | +  completedProjects: number = 0;
 | 
											
												
													
														|  | 
 |  | +  currentMonthProjects: number = 0;
 | 
											
												
													
														|  | 
 |  | +  avgCustomerRating: number = 0;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  // 创建项目引导(保留原有功能)
 | 
											
												
													
														|  |    showCreateGuide: boolean = false;
 |  |    showCreateGuide: boolean = false;
 | 
											
												
													
														|  |    defaultProjectName: string = '';
 |  |    defaultProjectName: string = '';
 | 
											
												
													
														|  |    projectName: string = '';
 |  |    projectName: string = '';
 | 
											
												
													
														|  |    creating: boolean = false;
 |  |    creating: boolean = false;
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -  // 历史项目(当前群聊无项目时展示)
 |  | 
 | 
											
												
													
														|  |    historyProjects: FmodeObject[] = [];
 |  |    historyProjects: FmodeObject[] = [];
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    constructor(
 |  |    constructor(
 | 
											
										
											
												
													
														|  | @@ -97,7 +161,7 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    /**
 |  |    /**
 | 
											
												
													
														|  | -   * 加载数据主流程(参考 page-chat-context 实现)
 |  | 
 | 
											
												
													
														|  | 
 |  | +   * 加载数据主流程
 | 
											
												
													
														|  |     */
 |  |     */
 | 
											
												
													
														|  |    async loadData() {
 |  |    async loadData() {
 | 
											
												
													
														|  |      try {
 |  |      try {
 | 
											
										
											
												
													
														|  | @@ -112,14 +176,13 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |        wxdebug('1. SDK初始化完成', { cid: this.cid, appId: this.appId });
 |  |        wxdebug('1. SDK初始化完成', { cid: this.cid, appId: this.appId });
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -      // 2️⃣ 加载当前登录员工信息(由 WxworkAuthGuard 自动登录)
 |  | 
 | 
											
												
													
														|  | 
 |  | +      // 2️⃣ 加载当前登录员工信息
 | 
											
												
													
														|  |        this.loadingMessage = '获取用户信息...';
 |  |        this.loadingMessage = '获取用户信息...';
 | 
											
												
													
														|  |        try {
 |  |        try {
 | 
											
												
													
														|  |          this.currentUser = await this.wxwork.getCurrentUser();
 |  |          this.currentUser = await this.wxwork.getCurrentUser();
 | 
											
												
													
														|  |          wxdebug('2. 获取当前用户成功', this.currentUser?.toJSON());
 |  |          wxdebug('2. 获取当前用户成功', this.currentUser?.toJSON());
 | 
											
												
													
														|  |        } catch (err) {
 |  |        } catch (err) {
 | 
											
												
													
														|  |          console.error('获取当前用户失败:', err);
 |  |          console.error('获取当前用户失败:', err);
 | 
											
												
													
														|  | -        wxdebug('2. 获取当前用户失败', err);
 |  | 
 | 
											
												
													
														|  |          throw new Error('获取用户信息失败,请重试');
 |  |          throw new Error('获取用户信息失败,请重试');
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -133,60 +196,26 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |          wxdebug('3. getCurrentChat失败', err);
 |  |          wxdebug('3. getCurrentChat失败', err);
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -      // 4️⃣ 根据场景同步数据
 |  | 
 | 
											
												
													
														|  | 
 |  | +      // 4️⃣ 根据场景处理
 | 
											
												
													
														|  |        if (this.currentChat?.type === "chatId" && this.currentChat?.group) {
 |  |        if (this.currentChat?.type === "chatId" && this.currentChat?.group) {
 | 
											
												
													
														|  | -        // 群聊场景
 |  | 
 | 
											
												
													
														|  | -        wxdebug('4. 检测到群聊场景', this.currentChat.group);
 |  | 
 | 
											
												
													
														|  | -        this.loadingMessage = '同步群聊信息...';
 |  | 
 | 
											
												
													
														|  | -        try {
 |  | 
 | 
											
												
													
														|  | 
 |  | +        // 群聊场景 - 保留原有逻辑
 | 
											
												
													
														|  |            this.chatType = 'group';
 |  |            this.chatType = 'group';
 | 
											
												
													
														|  |            this.groupChat = await this.wxwork.syncGroupChat(this.currentChat.group);
 |  |            this.groupChat = await this.wxwork.syncGroupChat(this.currentChat.group);
 | 
											
												
													
														|  | -          wxdebug('5. 群聊同步完成', this.groupChat?.toJSON());
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -          // 处理群聊场景
 |  | 
 | 
											
												
													
														|  |            await this.handleGroupChatScene();
 |  |            await this.handleGroupChatScene();
 | 
											
												
													
														|  | -        } catch (err) {
 |  | 
 | 
											
												
													
														|  | -          console.error('群聊同步失败:', err);
 |  | 
 | 
											
												
													
														|  | -          wxdebug('5. 群聊同步失败', err);
 |  | 
 | 
											
												
													
														|  | -          throw new Error('群聊信息同步失败');
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  |        } else if (this.currentChat?.type === "userId" && this.currentChat?.id) {
 |  |        } else if (this.currentChat?.type === "userId" && this.currentChat?.id) {
 | 
											
												
													
														|  | -        // 联系人场景
 |  | 
 | 
											
												
													
														|  | -        wxdebug('4. 检测到联系人场景', { id: this.currentChat.id });
 |  | 
 | 
											
												
													
														|  | -        this.loadingMessage = '同步联系人信息...';
 |  | 
 | 
											
												
													
														|  | -        try {
 |  | 
 | 
											
												
													
														|  | 
 |  | +        // 联系人场景 - 保留原有逻辑
 | 
											
												
													
														|  |            this.chatType = 'contact';
 |  |            this.chatType = 'contact';
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -          // 获取完整联系人信息
 |  | 
 | 
											
												
													
														|  |            const contactInfo = await this.wecorp!.externalContact.get(this.currentChat.id);
 |  |            const contactInfo = await this.wecorp!.externalContact.get(this.currentChat.id);
 | 
											
												
													
														|  | -          wxdebug('5. 获取完整联系人信息', contactInfo);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |            this.contact = await this.wxwork.syncContact(contactInfo);
 |  |            this.contact = await this.wxwork.syncContact(contactInfo);
 | 
											
												
													
														|  | -          wxdebug('6. 联系人同步完成', this.contact?.toJSON());
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -          // 处理联系人场景
 |  | 
 | 
											
												
													
														|  |            await this.handleContactScene();
 |  |            await this.handleContactScene();
 | 
											
												
													
														|  | -        } catch (err) {
 |  | 
 | 
											
												
													
														|  | -          console.error('联系人同步失败:', err);
 |  | 
 | 
											
												
													
														|  | -          wxdebug('联系人同步失败', err);
 |  | 
 | 
											
												
													
														|  | -          throw new Error('联系人信息同步失败');
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  |        } else {
 |  |        } else {
 | 
											
												
													
														|  | -        // 未检测到有效场景
 |  | 
 | 
											
												
													
														|  | -        wxdebug('4. 未检测到有效场景', {
 |  | 
 | 
											
												
													
														|  | -          currentChat: this.currentChat,
 |  | 
 | 
											
												
													
														|  | -          type: this.currentChat?.type,
 |  | 
 | 
											
												
													
														|  | -          hasGroup: !!this.currentChat?.group,
 |  | 
 | 
											
												
													
														|  | -          hasContact: !!this.currentChat?.contact,
 |  | 
 | 
											
												
													
														|  | -          hasId: !!this.currentChat?.id
 |  | 
 | 
											
												
													
														|  | -        });
 |  | 
 | 
											
												
													
														|  | -        throw new Error('无法识别当前会话类型,请在群聊或联系人会话中打开');
 |  | 
 | 
											
												
													
														|  | 
 |  | +        // 个人看板场景(默认)
 | 
											
												
													
														|  | 
 |  | +        this.chatType = 'personal';
 | 
											
												
													
														|  | 
 |  | +        await this.loadPersonalBoard();
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |        wxdebug('加载完成', {
 |  |        wxdebug('加载完成', {
 | 
											
												
													
														|  |          chatType: this.chatType,
 |  |          chatType: this.chatType,
 | 
											
												
													
														|  | -        hasGroupChat: !!this.groupChat,
 |  | 
 | 
											
												
													
														|  | -        hasContact: !!this.contact,
 |  | 
 | 
											
												
													
														|  |          hasCurrentUser: !!this.currentUser
 |  |          hasCurrentUser: !!this.currentUser
 | 
											
												
													
														|  |        });
 |  |        });
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -199,61 +228,446 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |    /**
 |  |    /**
 | 
											
												
													
														|  | -   * 处理群聊场景
 |  | 
 | 
											
												
													
														|  | 
 |  | +   * 加载个人看板数据
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async loadPersonalBoard() {
 | 
											
												
													
														|  | 
 |  | +    if (!this.currentUser) {
 | 
											
												
													
														|  | 
 |  | +      throw new Error('用户信息不存在');
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    this.loadingMessage = '加载个人信息...';
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      // 并行加载所有数据
 | 
											
												
													
														|  | 
 |  | +      await Promise.all([
 | 
											
												
													
														|  | 
 |  | +        this.loadProfileData(),
 | 
											
												
													
														|  | 
 |  | +        this.loadSkillRatings(),
 | 
											
												
													
														|  | 
 |  | +        this.loadCaseWorks(),
 | 
											
												
													
														|  | 
 |  | +        this.loadMonthlyStats(),
 | 
											
												
													
														|  | 
 |  | +        this.loadSelfEvaluation()
 | 
											
												
													
														|  | 
 |  | +      ]);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      console.log('✅ 个人看板数据加载完成');
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('加载个人看板数据失败:', err);
 | 
											
												
													
														|  | 
 |  | +      throw err;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 加载个人资料数据
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async loadProfileData() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      // 从Profile表获取最新数据
 | 
											
												
													
														|  | 
 |  | +      const query = new Parse.Query('Profile');
 | 
											
												
													
														|  | 
 |  | +      const profile = await query.get(this.currentUser!.id);
 | 
											
												
													
														|  | 
 |  | +      this.currentUser = profile;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      const data = profile.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +      
 | 
											
												
													
														|  | 
 |  | +      // 计算统计数据
 | 
											
												
													
														|  | 
 |  | +      await this.calculateStatistics();
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('加载个人资料失败:', err);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 加载技能评分
 | 
											
												
													
														|  |     */
 |  |     */
 | 
											
												
													
														|  | 
 |  | +  async loadSkillRatings() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      const data = this.currentUser!.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +      const skills = data.skillRatings || [];
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 如果没有技能评分,创建默认值
 | 
											
												
													
														|  | 
 |  | +      if (skills.length === 0) {
 | 
											
												
													
														|  | 
 |  | +        this.skillRatings = this.getDefaultSkillRatings();
 | 
											
												
													
														|  | 
 |  | +      } else {
 | 
											
												
													
														|  | 
 |  | +        this.skillRatings = skills;
 | 
											
												
													
														|  | 
 |  | +      }
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('加载技能评分失败:', err);
 | 
											
												
													
														|  | 
 |  | +      this.skillRatings = this.getDefaultSkillRatings();
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 加载案例作品
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async loadCaseWorks() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      const data = this.currentUser!.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +      const caseProjectIds = data.caseWorks || [];
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      if (caseProjectIds.length === 0) {
 | 
											
												
													
														|  | 
 |  | +        this.caseWorks = [];
 | 
											
												
													
														|  | 
 |  | +        return;
 | 
											
												
													
														|  | 
 |  | +      }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 查询案例对应的项目
 | 
											
												
													
														|  | 
 |  | +      const query = new Parse.Query('Project');
 | 
											
												
													
														|  | 
 |  | +      query.containedIn('objectId', caseProjectIds);
 | 
											
												
													
														|  | 
 |  | +      query.equalTo('currentStage', '售后归档');
 | 
											
												
													
														|  | 
 |  | +      query.notEqualTo('isDeleted', true);
 | 
											
												
													
														|  | 
 |  | +      query.include('contact');
 | 
											
												
													
														|  | 
 |  | +      query.descending('updatedAt');
 | 
											
												
													
														|  | 
 |  | +      query.limit(20);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      const projects = await query.find();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.caseWorks = projects.map(p => this.transformProjectToCase(p));
 | 
											
												
													
														|  | 
 |  | +      console.log(`✅ 加载了 ${this.caseWorks.length} 个案例作品`);
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('加载案例作品失败:', err);
 | 
											
												
													
														|  | 
 |  | +      this.caseWorks = [];
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 加载月度统计
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async loadMonthlyStats() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      // 查询最近6个月的项目
 | 
											
												
													
														|  | 
 |  | +      const sixMonthsAgo = new Date();
 | 
											
												
													
														|  | 
 |  | +      sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      const query = new Parse.Query('Project');
 | 
											
												
													
														|  | 
 |  | +      query.equalTo('assignee', this.currentUser!.toPointer());
 | 
											
												
													
														|  | 
 |  | +      query.greaterThanOrEqualTo('createdAt', sixMonthsAgo);
 | 
											
												
													
														|  | 
 |  | +      query.notEqualTo('isDeleted', true);
 | 
											
												
													
														|  | 
 |  | +      query.limit(1000);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      const projects = await query.find();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 按月分组统计
 | 
											
												
													
														|  | 
 |  | +      const monthlyMap = new Map<string, MonthlyStats>();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      projects.forEach(p => {
 | 
											
												
													
														|  | 
 |  | +        const date = p.get('createdAt');
 | 
											
												
													
														|  | 
 |  | +        const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
 | 
											
												
													
														|  | 
 |  | +        
 | 
											
												
													
														|  | 
 |  | +        if (!monthlyMap.has(monthKey)) {
 | 
											
												
													
														|  | 
 |  | +          monthlyMap.set(monthKey, {
 | 
											
												
													
														|  | 
 |  | +            month: monthKey,
 | 
											
												
													
														|  | 
 |  | +            totalProjects: 0,
 | 
											
												
													
														|  | 
 |  | +            completedProjects: 0,
 | 
											
												
													
														|  | 
 |  | +            revenue: 0,
 | 
											
												
													
														|  | 
 |  | +            avgScore: 0
 | 
											
												
													
														|  | 
 |  | +          });
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        const stats = monthlyMap.get(monthKey)!;
 | 
											
												
													
														|  | 
 |  | +        stats.totalProjects++;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        if (p.get('currentStage') === '售后归档' || p.get('status') === '已完成') {
 | 
											
												
													
														|  | 
 |  | +          stats.completedProjects++;
 | 
											
												
													
														|  | 
 |  | +          
 | 
											
												
													
														|  | 
 |  | +          // 计算收入
 | 
											
												
													
														|  | 
 |  | +          const pricing = p.get('data')?.pricing || {};
 | 
											
												
													
														|  | 
 |  | +          const totalPrice = pricing.totalAmount || pricing.total || pricing.finalPrice || 0;
 | 
											
												
													
														|  | 
 |  | +          stats.revenue += totalPrice;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +      });
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 转换为数组并排序
 | 
											
												
													
														|  | 
 |  | +      this.monthlyStats = Array.from(monthlyMap.values())
 | 
											
												
													
														|  | 
 |  | +        .sort((a, b) => b.month.localeCompare(a.month))
 | 
											
												
													
														|  | 
 |  | +        .slice(0, 6);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      console.log(`✅ 加载了 ${this.monthlyStats.length} 个月的统计数据`);
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('加载月度统计失败:', err);
 | 
											
												
													
														|  | 
 |  | +      this.monthlyStats = [];
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 加载自我评价
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async loadSelfEvaluation() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      const data = this.currentUser!.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +      const evaluation = data.selfEvaluation;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      if (evaluation) {
 | 
											
												
													
														|  | 
 |  | +        this.selfEvaluation = {
 | 
											
												
													
														|  | 
 |  | +          strengths: evaluation.strengths || [],
 | 
											
												
													
														|  | 
 |  | +          improvements: evaluation.improvements || [],
 | 
											
												
													
														|  | 
 |  | +          personalStatement: evaluation.personalStatement || '',
 | 
											
												
													
														|  | 
 |  | +          lastUpdated: evaluation.lastUpdated ? new Date(evaluation.lastUpdated) : new Date()
 | 
											
												
													
														|  | 
 |  | +        };
 | 
											
												
													
														|  | 
 |  | +      } else {
 | 
											
												
													
														|  | 
 |  | +        // 默认值
 | 
											
												
													
														|  | 
 |  | +        this.selfEvaluation = {
 | 
											
												
													
														|  | 
 |  | +          strengths: ['专业扎实', '责任心强'],
 | 
											
												
													
														|  | 
 |  | +          improvements: ['沟通效率', '时间管理'],
 | 
											
												
													
														|  | 
 |  | +          personalStatement: '我是一名热爱设计的专业人士,致力于为客户提供优质的服务。',
 | 
											
												
													
														|  | 
 |  | +          lastUpdated: new Date()
 | 
											
												
													
														|  | 
 |  | +        };
 | 
											
												
													
														|  | 
 |  | +      }
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('加载自我评价失败:', err);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 计算统计数据
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async calculateStatistics() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      const profilePointer = this.currentUser!.toPointer();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 查询总项目数
 | 
											
												
													
														|  | 
 |  | +      const totalQuery = new Parse.Query('Project');
 | 
											
												
													
														|  | 
 |  | +      totalQuery.equalTo('assignee', profilePointer);
 | 
											
												
													
														|  | 
 |  | +      totalQuery.notEqualTo('isDeleted', true);
 | 
											
												
													
														|  | 
 |  | +      this.totalProjects = await totalQuery.count();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 查询已完成项目数
 | 
											
												
													
														|  | 
 |  | +      const completedQuery = new Parse.Query('Project');
 | 
											
												
													
														|  | 
 |  | +      completedQuery.equalTo('assignee', profilePointer);
 | 
											
												
													
														|  | 
 |  | +      completedQuery.equalTo('currentStage', '售后归档');
 | 
											
												
													
														|  | 
 |  | +      completedQuery.notEqualTo('isDeleted', true);
 | 
											
												
													
														|  | 
 |  | +      this.completedProjects = await completedQuery.count();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 查询本月项目数
 | 
											
												
													
														|  | 
 |  | +      const currentMonth = new Date();
 | 
											
												
													
														|  | 
 |  | +      currentMonth.setDate(1);
 | 
											
												
													
														|  | 
 |  | +      currentMonth.setHours(0, 0, 0, 0);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      const monthQuery = new Parse.Query('Project');
 | 
											
												
													
														|  | 
 |  | +      monthQuery.equalTo('assignee', profilePointer);
 | 
											
												
													
														|  | 
 |  | +      monthQuery.greaterThanOrEqualTo('createdAt', currentMonth);
 | 
											
												
													
														|  | 
 |  | +      monthQuery.notEqualTo('isDeleted', true);
 | 
											
												
													
														|  | 
 |  | +      this.currentMonthProjects = await monthQuery.count();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      console.log(`✅ 统计数据:总项目=${this.totalProjects}, 已完成=${this.completedProjects}, 本月=${this.currentMonthProjects}`);
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('计算统计数据失败:', err);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 将项目转换为案例
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  transformProjectToCase(project: FmodeObject): CaseWork {
 | 
											
												
													
														|  | 
 |  | +    const data = project.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +    const pricing = data.pricing || {};
 | 
											
												
													
														|  | 
 |  | +    const contact = project.get('contact');
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    // 获取封面图片
 | 
											
												
													
														|  | 
 |  | +    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];
 | 
											
												
													
														|  | 
 |  | +      }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    return {
 | 
											
												
													
														|  | 
 |  | +      id: project.id,
 | 
											
												
													
														|  | 
 |  | +      projectId: project.id,
 | 
											
												
													
														|  | 
 |  | +      projectTitle: project.get('title') || '未命名项目',
 | 
											
												
													
														|  | 
 |  | +      coverImage: coverImage,
 | 
											
												
													
														|  | 
 |  | +      description: data.description || project.get('title') || '',
 | 
											
												
													
														|  | 
 |  | +      tags: data.tags || data.stylePreferences || [],
 | 
											
												
													
														|  | 
 |  | +      completionDate: project.get('updatedAt') || new Date(),
 | 
											
												
													
														|  | 
 |  | +      customerName: contact?.get('name') || '客户',
 | 
											
												
													
														|  | 
 |  | +      status: project.get('status') || '已完成',
 | 
											
												
													
														|  | 
 |  | +      totalPrice: pricing.totalAmount || pricing.total || pricing.finalPrice,
 | 
											
												
													
														|  | 
 |  | +      roomType: data.roomType || data.spaceType
 | 
											
												
													
														|  | 
 |  | +    };
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 获取默认技能评分
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  getDefaultSkillRatings(): SkillRating[] {
 | 
											
												
													
														|  | 
 |  | +    const role = this.currentUser?.get('roleName') || '组员';
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    if (role === '组员' || role === '设计师') {
 | 
											
												
													
														|  | 
 |  | +      return [
 | 
											
												
													
														|  | 
 |  | +        { 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: '项目管理' }
 | 
											
												
													
														|  | 
 |  | +      ];
 | 
											
												
													
														|  | 
 |  | +    } else if (role === '客服') {
 | 
											
												
													
														|  | 
 |  | +      return [
 | 
											
												
													
														|  | 
 |  | +        { 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: '项目管理' }
 | 
											
												
													
														|  | 
 |  | +      ];
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    return [];
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  // ==================== 编辑功能 ====================
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 打开编辑自我评价
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  openEditEvaluation() {
 | 
											
												
													
														|  | 
 |  | +    this.editingEvaluation = JSON.parse(JSON.stringify(this.selfEvaluation));
 | 
											
												
													
														|  | 
 |  | +    this.showEditEvaluation = true;
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 保存自我评价
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async saveEvaluation() {
 | 
											
												
													
														|  | 
 |  | +    if (!this.editingEvaluation) return;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      this.editingEvaluation.lastUpdated = new Date();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      const data = this.currentUser!.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +      data.selfEvaluation = this.editingEvaluation;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.currentUser!.set('data', data);
 | 
											
												
													
														|  | 
 |  | +      await this.currentUser!.save();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.selfEvaluation = this.editingEvaluation;
 | 
											
												
													
														|  | 
 |  | +      this.showEditEvaluation = false;
 | 
											
												
													
														|  | 
 |  | +      this.editingEvaluation = null;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('保存成功!');
 | 
											
												
													
														|  | 
 |  | +    } catch (err: any) {
 | 
											
												
													
														|  | 
 |  | +      console.error('保存自我评价失败:', err);
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('保存失败: ' + (err.message || '未知错误'));
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 打开案例选择器
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async openCaseSelector() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      this.loadingMessage = '加载可选项目...';
 | 
											
												
													
														|  | 
 |  | +      this.loading = true;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 查询已完成的项目
 | 
											
												
													
														|  | 
 |  | +      const query = new Parse.Query('Project');
 | 
											
												
													
														|  | 
 |  | +      query.equalTo('assignee', this.currentUser!.toPointer());
 | 
											
												
													
														|  | 
 |  | +      query.equalTo('currentStage', '售后归档');
 | 
											
												
													
														|  | 
 |  | +      query.notEqualTo('isDeleted', true);
 | 
											
												
													
														|  | 
 |  | +      query.include('contact');
 | 
											
												
													
														|  | 
 |  | +      query.descending('updatedAt');
 | 
											
												
													
														|  | 
 |  | +      query.limit(100);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.availableProjects = await query.find();
 | 
											
												
													
														|  | 
 |  | +      this.selectedProjectIds = this.caseWorks.map(c => c.projectId);
 | 
											
												
													
														|  | 
 |  | +      
 | 
											
												
													
														|  | 
 |  | +      this.showCaseSelector = true;
 | 
											
												
													
														|  | 
 |  | +      console.log(`✅ 找到 ${this.availableProjects.length} 个可选项目`);
 | 
											
												
													
														|  | 
 |  | +    } catch (err) {
 | 
											
												
													
														|  | 
 |  | +      console.error('加载可选项目失败:', err);
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('加载失败,请重试');
 | 
											
												
													
														|  | 
 |  | +    } finally {
 | 
											
												
													
														|  | 
 |  | +      this.loading = false;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 切换项目选择
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  toggleProjectSelection(projectId: string) {
 | 
											
												
													
														|  | 
 |  | +    const index = this.selectedProjectIds.indexOf(projectId);
 | 
											
												
													
														|  | 
 |  | +    if (index > -1) {
 | 
											
												
													
														|  | 
 |  | +      this.selectedProjectIds.splice(index, 1);
 | 
											
												
													
														|  | 
 |  | +    } else {
 | 
											
												
													
														|  | 
 |  | +      if (this.selectedProjectIds.length >= 12) {
 | 
											
												
													
														|  | 
 |  | +        window?.fmode?.alert('最多选择12个案例');
 | 
											
												
													
														|  | 
 |  | +        return;
 | 
											
												
													
														|  | 
 |  | +      }
 | 
											
												
													
														|  | 
 |  | +      this.selectedProjectIds.push(projectId);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 保存案例选择
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async saveCaseSelection() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      const data = this.currentUser!.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +      data.caseWorks = this.selectedProjectIds;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.currentUser!.set('data', data);
 | 
											
												
													
														|  | 
 |  | +      await this.currentUser!.save();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      // 重新加载案例
 | 
											
												
													
														|  | 
 |  | +      await this.loadCaseWorks();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.showCaseSelector = false;
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('保存成功!');
 | 
											
												
													
														|  | 
 |  | +    } catch (err: any) {
 | 
											
												
													
														|  | 
 |  | +      console.error('保存案例选择失败:', err);
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('保存失败: ' + (err.message || '未知错误'));
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  /**
 | 
											
												
													
														|  | 
 |  | +   * 保存技能评分
 | 
											
												
													
														|  | 
 |  | +   */
 | 
											
												
													
														|  | 
 |  | +  async saveSkillRatings() {
 | 
											
												
													
														|  | 
 |  | +    try {
 | 
											
												
													
														|  | 
 |  | +      const data = this.currentUser!.get('data') || {};
 | 
											
												
													
														|  | 
 |  | +      data.skillRatings = this.skillRatings;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.currentUser!.set('data', data);
 | 
											
												
													
														|  | 
 |  | +      await this.currentUser!.save();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +      this.showSkillEditor = false;
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('保存成功!');
 | 
											
												
													
														|  | 
 |  | +    } catch (err: any) {
 | 
											
												
													
														|  | 
 |  | +      console.error('保存技能评分失败:', err);
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('保存失败: ' + (err.message || '未知错误'));
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  // ==================== 原有群聊/联系人场景功能(保留) ====================
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |    async handleGroupChatScene() {
 |  |    async handleGroupChatScene() {
 | 
											
												
													
														|  |      this.loadingMessage = '查询项目信息...';
 |  |      this.loadingMessage = '查询项目信息...';
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    // 查询群聊关联的项目
 |  | 
 | 
											
												
													
														|  |      const projectPointer = this.groupChat!.get('project');
 |  |      const projectPointer = this.groupChat!.get('project');
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      if (projectPointer) {
 |  |      if (projectPointer) {
 | 
											
												
													
														|  | -      // 有项目,加载项目详情
 |  | 
 | 
											
												
													
														|  |        let pid = projectPointer.id || projectPointer.objectId
 |  |        let pid = projectPointer.id || projectPointer.objectId
 | 
											
												
													
														|  |        try {
 |  |        try {
 | 
											
												
													
														|  |          const query = new Parse.Query('Project');
 |  |          const query = new Parse.Query('Project');
 | 
											
												
													
														|  |          query.include('contact', 'assignee');
 |  |          query.include('contact', 'assignee');
 | 
											
												
													
														|  |          this.project = await query.get(pid);
 |  |          this.project = await query.get(pid);
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        wxdebug('找到项目', this.project.toJSON());
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        // 跳转项目详情
 |  | 
 | 
											
												
													
														|  |          await this.navigateToProjectDetail();
 |  |          await this.navigateToProjectDetail();
 | 
											
												
													
														|  |        } catch (err) {
 |  |        } catch (err) {
 | 
											
												
													
														|  |          console.error('加载项目失败:', err);
 |  |          console.error('加载项目失败:', err);
 | 
											
												
													
														|  | -        wxdebug('加载项目失败', err);
 |  | 
 | 
											
												
													
														|  |          this.error = '项目已删除或无权访问';
 |  |          this.error = '项目已删除或无权访问';
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  |      } else {
 |  |      } else {
 | 
											
												
													
														|  | -      // 无项目,查询历史项目并显示创建引导
 |  | 
 | 
											
												
													
														|  |        await this.loadHistoryProjects();
 |  |        await this.loadHistoryProjects();
 | 
											
												
													
														|  |        this.showCreateProjectGuide();
 |  |        this.showCreateProjectGuide();
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 处理联系人场景
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    async handleContactScene() {
 |  |    async handleContactScene() {
 | 
											
												
													
														|  | -    wxdebug('联系人场景,跳转客户画像', {
 |  | 
 | 
											
												
													
														|  | -      contactId: this.contact!.id,
 |  | 
 | 
											
												
													
														|  | -      contactName: this.contact!.get('name')
 |  | 
 | 
											
												
													
														|  | -    });
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    // 跳转客户画像页面
 |  | 
 | 
											
												
													
														|  |      await this.router.navigate(['/wxwork', this.cid, 'contact', this.contact!.id], {
 |  |      await this.router.navigate(['/wxwork', this.cid, 'contact', this.contact!.id], {
 | 
											
												
													
														|  | -      queryParams: {
 |  | 
 | 
											
												
													
														|  | -        profileId: this.currentUser!.id
 |  | 
 | 
											
												
													
														|  | -      }
 |  | 
 | 
											
												
													
														|  | 
 |  | +      queryParams: { profileId: this.currentUser!.id }
 | 
											
												
													
														|  |      });
 |  |      });
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 加载历史项目(当前群聊相关的其他项目)
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    async loadHistoryProjects() {
 |  |    async loadHistoryProjects() {
 | 
											
												
													
														|  |      try {
 |  |      try {
 | 
											
												
													
														|  | -      // 通过 ProjectGroup 查询该群聊的所有项目
 |  | 
 | 
											
												
													
														|  |        const pgQuery = new Parse.Query('ProjectGroup');
 |  |        const pgQuery = new Parse.Query('ProjectGroup');
 | 
											
												
													
														|  |        pgQuery.equalTo('groupChat', this.groupChat!.toPointer());
 |  |        pgQuery.equalTo('groupChat', this.groupChat!.toPointer());
 | 
											
												
													
														|  |        pgQuery.include('project');
 |  |        pgQuery.include('project');
 | 
											
										
											
												
													
														|  | @@ -263,53 +677,32 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |        this.historyProjects = projectGroups
 |  |        this.historyProjects = projectGroups
 | 
											
												
													
														|  |          .map((pg: any) => pg.get('project'))
 |  |          .map((pg: any) => pg.get('project'))
 | 
											
												
													
														|  |          .filter((p: any) => p && !p.get('isDeleted'));
 |  |          .filter((p: any) => p && !p.get('isDeleted'));
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -      wxdebug('找到历史项目', { count: this.historyProjects.length });
 |  | 
 | 
											
												
													
														|  |      } catch (err) {
 |  |      } catch (err) {
 | 
											
												
													
														|  |        console.error('加载历史项目失败:', err);
 |  |        console.error('加载历史项目失败:', err);
 | 
											
												
													
														|  | -      wxdebug('加载历史项目失败', err);
 |  | 
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 显示创建项目引导
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    showCreateProjectGuide() {
 |  |    showCreateProjectGuide() {
 | 
											
												
													
														|  |      this.showCreateGuide = true;
 |  |      this.showCreateGuide = true;
 | 
											
												
													
														|  |      this.defaultProjectName = this.groupChat!.get('name') || '新项目';
 |  |      this.defaultProjectName = this.groupChat!.get('name') || '新项目';
 | 
											
												
													
														|  |      this.projectName = this.defaultProjectName;
 |  |      this.projectName = this.defaultProjectName;
 | 
											
												
													
														|  | -    wxdebug('显示创建项目引导', {
 |  | 
 | 
											
												
													
														|  | -      groupName: this.groupChat!.get('name'),
 |  | 
 | 
											
												
													
														|  | -      historyProjectsCount: this.historyProjects.length
 |  | 
 | 
											
												
													
														|  | -    });
 |  | 
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 创建项目
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    async createProject() {
 |  |    async createProject() {
 | 
											
												
													
														|  |      if (!this.projectName.trim()) {
 |  |      if (!this.projectName.trim()) {
 | 
											
												
													
														|  | -     window?.fmode?.alert('请输入项目名称');
 |  | 
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('请输入项目名称');
 | 
											
												
													
														|  |        return;
 |  |        return;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    // 权限检查
 |  | 
 | 
											
												
													
														|  |      const role = this.currentUser!.get('roleName');
 |  |      const role = this.currentUser!.get('roleName');
 | 
											
												
													
														|  |      if (!['客服', '组长', '管理员'].includes(role)) {
 |  |      if (!['客服', '组长', '管理员'].includes(role)) {
 | 
											
												
													
														|  | -     window?.fmode?.alert('您没有权限创建项目');
 |  | 
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('您没有权限创建项目');
 | 
											
												
													
														|  |        return;
 |  |        return;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      try {
 |  |      try {
 | 
											
												
													
														|  |        this.creating = true;
 |  |        this.creating = true;
 | 
											
												
													
														|  | -      wxdebug('开始创建项目', {
 |  | 
 | 
											
												
													
														|  | -        projectName: this.projectName,
 |  | 
 | 
											
												
													
														|  | -        groupChatId: this.groupChat!.id,
 |  | 
 | 
											
												
													
														|  | -        currentUserId: this.currentUser!.id,
 |  | 
 | 
											
												
													
														|  | -        role: role
 |  | 
 | 
											
												
													
														|  | -      });
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -      // 1. 创建项目
 |  | 
 | 
											
												
													
														|  |        const Project = Parse.Object.extend('Project');
 |  |        const Project = Parse.Object.extend('Project');
 | 
											
												
													
														|  |        const project = new Project();
 |  |        const project = new Project();
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -324,14 +717,10 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |        });
 |  |        });
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |        await project.save();
 |  |        await project.save();
 | 
											
												
													
														|  | -      wxdebug('项目创建成功', { projectId: project.id });
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -      // 2. 关联群聊
 |  | 
 | 
											
												
													
														|  |        this.groupChat!.set('project', project.toPointer());
 |  |        this.groupChat!.set('project', project.toPointer());
 | 
											
												
													
														|  |        await this.groupChat!.save();
 |  |        await this.groupChat!.save();
 | 
											
												
													
														|  | -      wxdebug('群聊关联项目成功');
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -      // 3. 创建 ProjectGroup 关联(支持多项目多群)
 |  | 
 | 
											
												
													
														|  |        const ProjectGroup = Parse.Object.extend('ProjectGroup');
 |  |        const ProjectGroup = Parse.Object.extend('ProjectGroup');
 | 
											
												
													
														|  |        const pg = new ProjectGroup();
 |  |        const pg = new ProjectGroup();
 | 
											
												
													
														|  |        pg.set('project', project.toPointer());
 |  |        pg.set('project', project.toPointer());
 | 
											
										
											
												
													
														|  | @@ -339,78 +728,48 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |        pg.set('isPrimary', true);
 |  |        pg.set('isPrimary', true);
 | 
											
												
													
														|  |        pg.set('company', this.currentUser!.get('company'));
 |  |        pg.set('company', this.currentUser!.get('company'));
 | 
											
												
													
														|  |        await pg.save();
 |  |        await pg.save();
 | 
											
												
													
														|  | -      wxdebug('ProjectGroup关联创建成功');
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -      // 4. 记录活动日志
 |  | 
 | 
											
												
													
														|  | -      try {
 |  | 
 | 
											
												
													
														|  | -        await this.activityLogService.logActivity({
 |  | 
 | 
											
												
													
														|  | -          actorId: this.currentUser!.id,
 |  | 
 | 
											
												
													
														|  | -          actorName: this.currentUser!.get('name') || '系统',
 |  | 
 | 
											
												
													
														|  | -          actorRole: role,
 |  | 
 | 
											
												
													
														|  | -          actionType: 'create',
 |  | 
 | 
											
												
													
														|  | -          module: 'project',
 |  | 
 | 
											
												
													
														|  | -          entityType: 'Project',
 |  | 
 | 
											
												
													
														|  | -          entityId: project.id,
 |  | 
 | 
											
												
													
														|  | -          entityName: this.projectName.trim(),
 |  | 
 | 
											
												
													
														|  | -          description: '创建了新项目',
 |  | 
 | 
											
												
													
														|  | -          metadata: {
 |  | 
 | 
											
												
													
														|  | -            createdFrom: 'wxwork_groupchat',
 |  | 
 | 
											
												
													
														|  | -            groupChatId: this.groupChat!.id,
 |  | 
 | 
											
												
													
														|  | -            status: '待分配',
 |  | 
 | 
											
												
													
														|  | -            stage: '订单分配'
 |  | 
 | 
											
												
													
														|  | -          }
 |  | 
 | 
											
												
													
														|  | -        });
 |  | 
 | 
											
												
													
														|  | -        wxdebug('活动日志记录成功');
 |  | 
 | 
											
												
													
														|  | -      } catch (logError) {
 |  | 
 | 
											
												
													
														|  | -        console.error('记录活动日志失败:', logError);
 |  | 
 | 
											
												
													
														|  | -        // 活动日志失败不影响主流程
 |  | 
 | 
											
												
													
														|  | -      }
 |  | 
 | 
											
												
													
														|  | 
 |  | +      await this.activityLogService.logActivity({
 | 
											
												
													
														|  | 
 |  | +        actorId: this.currentUser!.id,
 | 
											
												
													
														|  | 
 |  | +        actorName: this.currentUser!.get('name') || '系统',
 | 
											
												
													
														|  | 
 |  | +        actorRole: role,
 | 
											
												
													
														|  | 
 |  | +        actionType: 'create',
 | 
											
												
													
														|  | 
 |  | +        module: 'project',
 | 
											
												
													
														|  | 
 |  | +        entityType: 'Project',
 | 
											
												
													
														|  | 
 |  | +        entityId: project.id,
 | 
											
												
													
														|  | 
 |  | +        entityName: this.projectName.trim(),
 | 
											
												
													
														|  | 
 |  | +        description: '创建了新项目',
 | 
											
												
													
														|  | 
 |  | +        metadata: {
 | 
											
												
													
														|  | 
 |  | +          createdFrom: 'wxwork_groupchat',
 | 
											
												
													
														|  | 
 |  | +          groupChatId: this.groupChat!.id,
 | 
											
												
													
														|  | 
 |  | +          status: '待分配',
 | 
											
												
													
														|  | 
 |  | +          stage: '订单分配'
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +      });
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -      // 5. 跳转项目详情
 |  | 
 | 
											
												
													
														|  |        this.project = project;
 |  |        this.project = project;
 | 
											
												
													
														|  |        await this.navigateToProjectDetail();
 |  |        await this.navigateToProjectDetail();
 | 
											
												
													
														|  |      } catch (err: any) {
 |  |      } catch (err: any) {
 | 
											
												
													
														|  |        console.error('创建项目失败:', err);
 |  |        console.error('创建项目失败:', err);
 | 
											
												
													
														|  | -      wxdebug('创建项目失败', err);
 |  | 
 | 
											
												
													
														|  | -     window?.fmode?.alert('创建失败: ' + (err.message || '未知错误'));
 |  | 
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('创建失败: ' + (err.message || '未知错误'));
 | 
											
												
													
														|  |      } finally {
 |  |      } finally {
 | 
											
												
													
														|  |        this.creating = false;
 |  |        this.creating = false;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 选择历史项目
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    async selectHistoryProject(project: FmodeObject) {
 |  |    async selectHistoryProject(project: FmodeObject) {
 | 
											
												
													
														|  |      try {
 |  |      try {
 | 
											
												
													
														|  | -      wxdebug('选择历史项目', {
 |  | 
 | 
											
												
													
														|  | -        projectId: project.id,
 |  | 
 | 
											
												
													
														|  | -        projectTitle: project.get('title')
 |  | 
 | 
											
												
													
														|  | -      });
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -      // 更新群聊的当前项目
 |  | 
 | 
											
												
													
														|  |        this.groupChat!.set('project', project.toPointer());
 |  |        this.groupChat!.set('project', project.toPointer());
 | 
											
												
													
														|  |        await this.groupChat!.save();
 |  |        await this.groupChat!.save();
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -      // 跳转项目详情
 |  | 
 | 
											
												
													
														|  |        this.project = project;
 |  |        this.project = project;
 | 
											
												
													
														|  |        await this.navigateToProjectDetail();
 |  |        await this.navigateToProjectDetail();
 | 
											
												
													
														|  |      } catch (err: any) {
 |  |      } catch (err: any) {
 | 
											
												
													
														|  |        console.error('关联项目失败:', err);
 |  |        console.error('关联项目失败:', err);
 | 
											
												
													
														|  | -     window?.fmode?.alert('关联失败: ' + (err.message || '未知错误'));
 |  | 
 | 
											
												
													
														|  | 
 |  | +      window?.fmode?.alert('关联失败: ' + (err.message || '未知错误'));
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 跳转项目详情
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    async navigateToProjectDetail() {
 |  |    async navigateToProjectDetail() {
 | 
											
												
													
														|  | -    wxdebug('跳转项目详情', {
 |  | 
 | 
											
												
													
														|  | -      projectId: this.project!.id,
 |  | 
 | 
											
												
													
														|  | -      cid: this.cid,
 |  | 
 | 
											
												
													
														|  | -      groupChatId: this.groupChat?.id
 |  | 
 | 
											
												
													
														|  | -    });
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |      await this.router.navigate(['/wxwork', this.cid, 'project', this.project!.id], {
 |  |      await this.router.navigate(['/wxwork', this.cid, 'project', this.project!.id], {
 | 
											
												
													
														|  |        queryParams: {
 |  |        queryParams: {
 | 
											
												
													
														|  |          groupId: this.groupChat?.id,
 |  |          groupId: this.groupChat?.id,
 | 
											
										
											
												
													
														|  | @@ -419,36 +778,26 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |      });
 |  |      });
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 重新加载
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  | 
 |  | +  // ==================== 工具方法 ====================
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |    async reload() {
 |  |    async reload() {
 | 
											
												
													
														|  |      this.error = null;
 |  |      this.error = null;
 | 
											
												
													
														|  |      this.showCreateGuide = false;
 |  |      this.showCreateGuide = false;
 | 
											
												
													
														|  |      this.historyProjects = [];
 |  |      this.historyProjects = [];
 | 
											
												
													
														|  | -    this.chatType = 'none';
 |  | 
 | 
											
												
													
														|  | 
 |  | +    this.chatType = 'personal';
 | 
											
												
													
														|  |      await this.loadData();
 |  |      await this.loadData();
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 获取当前员工姓名
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    getCurrentUserName(): string {
 |  |    getCurrentUserName(): string {
 | 
											
												
													
														|  |      if (!this.currentUser) return '未知';
 |  |      if (!this.currentUser) return '未知';
 | 
											
												
													
														|  |      return this.currentUser.get('name') || this.currentUser.get('userid') || '未知';
 |  |      return this.currentUser.get('name') || this.currentUser.get('userid') || '未知';
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 获取当前员工角色
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    getCurrentUserRole(): string {
 |  |    getCurrentUserRole(): string {
 | 
											
												
													
														|  |      if (!this.currentUser) return '未知';
 |  |      if (!this.currentUser) return '未知';
 | 
											
												
													
														|  |      return this.currentUser.get('roleName') || '未知';
 |  |      return this.currentUser.get('roleName') || '未知';
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 获取项目状态的显示样式类
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  |    getProjectStatusClass(status: string): string {
 |  |    getProjectStatusClass(status: string): string {
 | 
											
												
													
														|  |      const classMap: any = {
 |  |      const classMap: any = {
 | 
											
												
													
														|  |        '待分配': 'status-pending',
 |  |        '待分配': 'status-pending',
 | 
											
										
											
												
													
														|  | @@ -460,12 +809,49 @@ export class ProjectLoaderComponent implements OnInit {
 | 
											
												
													
														|  |      return classMap[status] || 'status-default';
 |  |      return classMap[status] || 'status-default';
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -  /**
 |  | 
 | 
											
												
													
														|  | -   * 格式化日期
 |  | 
 | 
											
												
													
														|  | -   */
 |  | 
 | 
											
												
													
														|  | -  formatDate(date: Date): string {
 |  | 
 | 
											
												
													
														|  | 
 |  | +  formatDate(date: Date | string): string {
 | 
											
												
													
														|  |      if (!date) return '';
 |  |      if (!date) return '';
 | 
											
												
													
														|  |      const d = new Date(date);
 |  |      const d = new Date(date);
 | 
											
												
													
														|  |      return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}`;
 |  |      return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}`;
 | 
											
												
													
														|  |    }
 |  |    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  formatMonth(monthStr: string): string {
 | 
											
												
													
														|  | 
 |  | +    const [year, month] = monthStr.split('-');
 | 
											
												
													
														|  | 
 |  | +    return `${year}年${month}月`;
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  formatCurrency(amount: number): string {
 | 
											
												
													
														|  | 
 |  | +    if (!amount) return '¥0';
 | 
											
												
													
														|  | 
 |  | +    return `¥${amount.toLocaleString()}`;
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  getScoreColor(score: number): string {
 | 
											
												
													
														|  | 
 |  | +    if (score >= 80) return 'score-high';
 | 
											
												
													
														|  | 
 |  | +    if (score >= 60) return 'score-medium';
 | 
											
												
													
														|  | 
 |  | +    return 'score-low';
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  getScoreProgress(current: number, target: number): number {
 | 
											
												
													
														|  | 
 |  | +    if (target === 0) return 0;
 | 
											
												
													
														|  | 
 |  | +    return Math.min((current / target) * 100, 100);
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  filterSkillsByCategory(category: string): SkillRating[] {
 | 
											
												
													
														|  | 
 |  | +    return this.skillRatings.filter(s => s.category === category);
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  getMaxMonthlyProjects(): number {
 | 
											
												
													
														|  | 
 |  | +    if (this.monthlyStats.length === 0) return 1;
 | 
											
												
													
														|  | 
 |  | +    return Math.max(...this.monthlyStats.map(m => m.totalProjects));
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  updateStrengths(value: string) {
 | 
											
												
													
														|  | 
 |  | +    if (!this.editingEvaluation) return;
 | 
											
												
													
														|  | 
 |  | +    this.editingEvaluation.strengths = value.split(',').map(s => s.trim()).filter(s => s.length > 0);
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +  updateImprovements(value: string) {
 | 
											
												
													
														|  | 
 |  | +    if (!this.editingEvaluation) return;
 | 
											
												
													
														|  | 
 |  | +    this.editingEvaluation.improvements = value.split(',').map(s => s.trim()).filter(s => s.length > 0);
 | 
											
												
													
														|  | 
 |  | +  }
 | 
											
												
													
														|  |  }
 |  |  }
 |