| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857 |
- import { Component, OnInit } from '@angular/core';
- import { CommonModule } from '@angular/common';
- import { Router, ActivatedRoute } from '@angular/router';
- import { FormsModule } from '@angular/forms';
- import { WxworkSDK, WxworkCorp } from 'fmode-ng/core';
- import { FmodeParse, FmodeObject } from 'fmode-ng/parse';
- import { ActivityLogService } from '../../../../app/services/activity-log.service';
- // WxworkCurrentChat 类型定义
- interface WxworkCurrentChat {
- type?: string;
- chatId?: string;
- group?: any;
- contact?: any;
- id?: string;
- [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[]){
- console.log(params)
- }
- const Parse = FmodeParse.with('nova');
- /**
- * 个人看板页面(重构自项目预加载页面)
- *
- * 功能:
- * 1. 展示个人信息和自我评价
- * 2. 技能评分和发展目标
- * 3. 案例作品集(从完成项目选择)
- * 4. 月度接单量统计
- * 5. 支持编辑个人资料和案例
- *
- * 路由:/wxwork/:cid/project-loader
- */
- @Component({
- selector: 'app-project-loader',
- standalone: true,
- imports: [CommonModule, FormsModule],
- templateUrl: './project-loader.component.html',
- styleUrls: ['./project-loader.component.scss']
- })
- export class ProjectLoaderComponent implements OnInit {
- // 基础数据
- cid: string = '';
- appId: string = 'crm';
- // 加载状态
- loading: boolean = true;
- loadingMessage: string = '正在加载...';
- error: string | null = null;
- // 企微SDK
- wxwork: WxworkSDK | null = null;
- wecorp: WxworkCorp | null = null;
- // 上下文数据
- currentUser: FmodeObject | null = null; // Profile
- currentChat: WxworkCurrentChat | null = null;
- chatType: 'group' | 'contact' | 'personal' = 'personal';
- groupChat: FmodeObject | null = null; // GroupChat
- contact: FmodeObject | null = null; // ContactInfo
- 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;
- defaultProjectName: string = '';
- projectName: string = '';
- creating: boolean = false;
- historyProjects: FmodeObject[] = [];
- constructor(
- private router: Router,
- private route: ActivatedRoute,
- private activityLogService: ActivityLogService
- ) {}
- async ngOnInit() {
- // 获取路由参数
- this.route.paramMap.subscribe(async params => {
- this.cid = params.get('cid') || localStorage.getItem("company") || '';
- this.appId = params.get('appId') || 'crm';
- if (!this.cid) {
- this.error = '缺少企业ID参数';
- this.loading = false;
- return;
- }
- await this.loadData();
- });
- }
- /**
- * 加载数据主流程
- */
- async loadData() {
- try {
- this.loading = true;
- this.loadingMessage = '初始化企微SDK...';
- // 1️⃣ 初始化 SDK
- // @ts-ignore - fmode-ng type issue
- this.wxwork = new WxworkSDK({ cid: this.cid, appId: this.appId });
- // @ts-ignore - fmode-ng type issue
- this.wecorp = new WxworkCorp(this.cid);
- wxdebug('1. SDK初始化完成', { cid: this.cid, appId: this.appId });
- // 2️⃣ 加载当前登录员工信息
- this.loadingMessage = '获取用户信息...';
- try {
- this.currentUser = await this.wxwork.getCurrentUser();
- wxdebug('2. 获取当前用户成功', this.currentUser?.toJSON());
- } catch (err) {
- console.error('获取当前用户失败:', err);
- throw new Error('获取用户信息失败,请重试');
- }
- // 3️⃣ 加载当前聊天上下文
- this.loadingMessage = '获取会话信息...';
- try {
- this.currentChat = await this.wxwork.getCurrentChat();
- wxdebug('3. getCurrentChat返回', this.currentChat);
- } catch (err) {
- console.error('getCurrentChat失败:', err);
- wxdebug('3. getCurrentChat失败', err);
- }
- // 4️⃣ 根据场景处理
- if (this.currentChat?.type === "chatId" && this.currentChat?.group) {
- // 群聊场景 - 保留原有逻辑
- this.chatType = 'group';
- this.groupChat = await this.wxwork.syncGroupChat(this.currentChat.group);
- await this.handleGroupChatScene();
- } else if (this.currentChat?.type === "userId" && this.currentChat?.id) {
- // 联系人场景 - 保留原有逻辑
- this.chatType = 'contact';
- const contactInfo = await this.wecorp!.externalContact.get(this.currentChat.id);
- this.contact = await this.wxwork.syncContact(contactInfo);
- await this.handleContactScene();
- } else {
- // 个人看板场景(默认)
- this.chatType = 'personal';
- await this.loadPersonalBoard();
- }
- wxdebug('加载完成', {
- chatType: this.chatType,
- hasCurrentUser: !!this.currentUser
- });
- } catch (err: any) {
- console.error('加载失败:', err);
- this.error = err.message || '加载失败,请重试';
- } finally {
- this.loading = false;
- }
- }
- /**
- * 加载个人看板数据
- */
- 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() {
- this.loadingMessage = '查询项目信息...';
- const projectPointer = this.groupChat!.get('project');
- if (projectPointer) {
- let pid = projectPointer.id || projectPointer.objectId
- try {
- const query = new Parse.Query('Project');
- query.include('contact', 'assignee');
- this.project = await query.get(pid);
- await this.navigateToProjectDetail();
- } catch (err) {
- console.error('加载项目失败:', err);
- this.error = '项目已删除或无权访问';
- }
- } else {
- await this.loadHistoryProjects();
- this.showCreateProjectGuide();
- }
- }
- async handleContactScene() {
- await this.router.navigate(['/wxwork', this.cid, 'contact', this.contact!.id], {
- queryParams: { profileId: this.currentUser!.id }
- });
- }
- async loadHistoryProjects() {
- try {
- const pgQuery = new Parse.Query('ProjectGroup');
- pgQuery.equalTo('groupChat', this.groupChat!.toPointer());
- pgQuery.include('project');
- pgQuery.descending('createdAt');
- const projectGroups = await pgQuery.find();
- this.historyProjects = projectGroups
- .map((pg: any) => pg.get('project'))
- .filter((p: any) => p && !p.get('isDeleted'));
- } catch (err) {
- console.error('加载历史项目失败:', err);
- }
- }
- showCreateProjectGuide() {
- this.showCreateGuide = true;
- this.defaultProjectName = this.groupChat!.get('name') || '新项目';
- this.projectName = this.defaultProjectName;
- }
- async createProject() {
- if (!this.projectName.trim()) {
- window?.fmode?.alert('请输入项目名称');
- return;
- }
- const role = this.currentUser!.get('roleName');
- if (!['客服', '组长', '管理员'].includes(role)) {
- window?.fmode?.alert('您没有权限创建项目');
- return;
- }
- try {
- this.creating = true;
- const Project = Parse.Object.extend('Project');
- const project = new Project();
- project.set('title', this.projectName.trim());
- project.set('company', this.currentUser!.get('company'));
- project.set('status', '待分配');
- project.set('currentStage', '订单分配');
- project.set('data', {
- createdBy: this.currentUser!.id,
- createdFrom: 'wxwork_groupchat',
- groupChatId: this.groupChat!.id
- });
- await project.save();
- this.groupChat!.set('project', project.toPointer());
- await this.groupChat!.save();
- const ProjectGroup = Parse.Object.extend('ProjectGroup');
- const pg = new ProjectGroup();
- pg.set('project', project.toPointer());
- pg.set('groupChat', this.groupChat!.toPointer());
- pg.set('isPrimary', true);
- pg.set('company', this.currentUser!.get('company'));
- await pg.save();
- 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: '订单分配'
- }
- });
- this.project = project;
- await this.navigateToProjectDetail();
- } catch (err: any) {
- console.error('创建项目失败:', err);
- window?.fmode?.alert('创建失败: ' + (err.message || '未知错误'));
- } finally {
- this.creating = false;
- }
- }
- async selectHistoryProject(project: FmodeObject) {
- try {
- this.groupChat!.set('project', project.toPointer());
- await this.groupChat!.save();
- this.project = project;
- await this.navigateToProjectDetail();
- } catch (err: any) {
- console.error('关联项目失败:', err);
- window?.fmode?.alert('关联失败: ' + (err.message || '未知错误'));
- }
- }
- async navigateToProjectDetail() {
- await this.router.navigate(['/wxwork', this.cid, 'project', this.project!.id], {
- queryParams: {
- groupId: this.groupChat?.id,
- profileId: this.currentUser!.id
- }
- });
- }
- // ==================== 工具方法 ====================
- async reload() {
- this.error = null;
- this.showCreateGuide = false;
- this.historyProjects = [];
- this.chatType = 'personal';
- await this.loadData();
- }
- getCurrentUserName(): string {
- if (!this.currentUser) return '未知';
- return this.currentUser.get('name') || this.currentUser.get('userid') || '未知';
- }
- getCurrentUserRole(): string {
- if (!this.currentUser) return '未知';
- return this.currentUser.get('roleName') || '未知';
- }
- getProjectStatusClass(status: string): string {
- const classMap: any = {
- '待分配': 'status-pending',
- '进行中': 'status-active',
- '已完成': 'status-completed',
- '已暂停': 'status-paused',
- '已取消': 'status-cancelled'
- };
- return classMap[status] || 'status-default';
- }
- formatDate(date: Date | string): string {
- if (!date) return '';
- const d = new Date(date);
- 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);
- }
- }
|