2024-10-24
完成客服板块项目列表页面(/customer-service/project-list)的真实Parse Server数据对接,并按照订单分配、确认需求、交付执行、售后四个阶段正确显示项目。
修改前:
columns = [
  { id: 'pending', name: '待分配' },
  { id: 'req', name: '需求深化' },
  { id: 'delivery', name: '交付中' },
  { id: 'done', name: '已完成' }
]
修改后:
columns = [
  { id: 'order', name: '订单分配' },
  { id: 'requirements', name: '确认需求' },
  { id: 'delivery', name: '交付执行' },
  { id: 'aftercare', name: '售后' }
]
statusOptions = [
  { value: 'all', label: '全部' },
  { value: 'order', label: '订单分配' },
  { value: 'requirements', label: '确认需求' },
  { value: 'delivery', label: '交付执行' },
  { value: 'aftercare', label: '售后' }
]
查询代码:
async loadProjects(): Promise<void> {
  const ProjectQuery = new Parse.Query('Project');
  ProjectQuery.equalTo('company', this.getCompanyPointer());
  ProjectQuery.equalTo('isDeleted', false);
  ProjectQuery.include('contact', 'assignee', 'owner');
  ProjectQuery.descending('updatedAt');
  ProjectQuery.limit(500);
  const projectObjects = await ProjectQuery.find();
  
  // 转换为前端格式
  const projects: Project[] = projectObjects.map((obj: FmodeObject) => {
    const contact = obj.get('contact');
    const assignee = obj.get('assignee');
    const mappedStage = this.mapStage(obj.get('currentStage'));
    
    return {
      id: obj.id,
      name: obj.get('title') || '未命名项目',
      customerName: contact?.get('name') || '未知客户',
      status: this.mapStatus(obj.get('status')),
      currentStage: mappedStage,
      assigneeName: assignee?.get('name') || '未分配',
      deadline: obj.get('deadline') || new Date(),
      // ... 其他字段
    };
  });
}
关键字段:
company: 公司指针(多租户隔离)isDeleted: 软删除标记contact: 客户信息(Pointer → ContactInfo)assignee: 负责设计师(Pointer → Profile)status: 项目状态(进行中/已完成/已暂停/已延期)currentStage: 当前阶段(订单分配/需求沟通/建模/软装/渲染等)deadline: 截止时间mapStage方法:
private mapStage(parseStage: string): ProjectStage {
  // 直接返回Parse Server的阶段,不做转换
  // Parse Server的currentStage字段包含:
  // 订单分配、需求沟通、建模、软装、渲染、后期、尾款结算、投诉处理等
  if (!parseStage) {
    return '需求沟通'; // 默认阶段
  }
  return parseStage as ProjectStage;
}
支持的阶段:
mapStatus方法:
private mapStatus(parseStatus: string): ProjectStatus {
  const statusMap: Record<string, ProjectStatus> = {
    '进行中': '进行中',
    '已完成': '已完成',
    '已暂停': '已暂停',
    '已延期': '已延期'
  };
  return statusMap[parseStatus] || '进行中';
}
判断条件:
private isOrderAssignment(p: Project): boolean {
  // 未分配设计师 或 currentStage为"订单分配"
  return !p.assigneeId || p.assigneeId.trim() === '' || p.currentStage === '订单分配';
}
包含项目:
判断条件:
private isRequirementsConfirmation(p: Project): boolean {
  const requirementStages: ProjectStage[] = ['需求沟通', '方案确认'];
  return !this.isAftercare(p) && !this.isOrderAssignment(p) && 
         requirementStages.includes(p.currentStage);
}
包含阶段:
判断条件:
private isDeliveryExecution(p: Project): boolean {
  const deliveryStages: ProjectStage[] = ['建模', '软装', '渲染', '后期', '尾款结算'];
  return !this.isAftercare(p) && !this.isOrderAssignment(p) && 
         deliveryStages.includes(p.currentStage);
}
包含阶段:
判断条件:
private isAftercare(p: Project): boolean {
  const aftercareStages: ProjectStage[] = ['投诉处理', '客户评价'];
  return p.status === '已完成' || aftercareStages.includes(p.currentStage);
}
包含情况:
修改后:
getProjectsByColumn(columnId: 'order' | 'requirements' | 'delivery' | 'aftercare'): ProjectListItem[] {
  const list = this.projects();
  switch (columnId) {
    case 'order':
      return list.filter(p => this.isOrderAssignment(p));
    case 'requirements':
      return list.filter(p => this.isRequirementsConfirmation(p));
    case 'delivery':
      return list.filter(p => this.isDeliveryExecution(p));
    case 'aftercare':
      return list.filter(p => this.isAftercare(p));
  }
}
修改后:
getColumnIdForProject(project: ProjectListItem): 'order' | 'requirements' | 'delivery' | 'aftercare' {
  if (this.isOrderAssignment(project)) return 'order';
  if (this.isRequirementsConfirmation(project)) return 'requirements';
  if (this.isDeliveryExecution(project)) return 'delivery';
  if (this.isAftercare(project)) return 'aftercare';
  return 'requirements'; // 默认为确认需求阶段
}
修改后:
navigateToProject(project: ProjectListItem, columnId: 'order' | 'requirements' | 'delivery' | 'aftercare') {
  const stageMapping = {
    'order': '订单分配',
    'requirements': project.currentStage || '需求沟通',
    'delivery': project.currentStage || '建模',
    'aftercare': '客户评价'
  };
  
  this.router.navigate(['/designer/project-detail', project.id], { 
    queryParams: { 
      role: 'customer-service',
      activeTab: 'progress',
      currentStage: stageMapping[columnId]
    } 
  });
}
修改前:
@if (col.id === 'pending') {
  <span class="pending-badge">待分配</span>
}
修改后:
@if (col.id === 'order') {
  <span class="pending-badge">待分配</span>
}
Parse Server (Project表)
  ↓
loadProjects() 查询
  ↓
mapStage() / mapStatus() 映射
  ↓
processProjects() 处理
  ↓
applyFiltersAndSorting() 筛选排序
  ↓
getProjectsByColumn() 按列分组
  ↓
HTML模板渲染
  ↓
四个看板列显示:
  - 订单分配 (order)
  - 确认需求 (requirements)
  - 交付执行 (delivery)
  - 售后 (aftercare)
| Parse Server currentStage | 看板列 | 列ID | 
|---|---|---|
| 订单分配 | 订单分配 | order | 
| 需求沟通 | 确认需求 | requirements | 
| 方案确认 | 确认需求 | requirements | 
| 建模 | 交付执行 | delivery | 
| 软装 | 交付执行 | delivery | 
| 渲染 | 交付执行 | delivery | 
| 后期 | 交付执行 | delivery | 
| 尾款结算 | 交付执行 | delivery | 
| 投诉处理 | 售后 | aftercare | 
| 客户评价 | 售后 | aftercare | 
| status=已完成 | 售后 | aftercare | 
yss-project/src/app/pages/customer-service/project-list/project-list.ts
yss-project/src/app/pages/customer-service/project-list/project-list.html
真实数据对接
四阶段看板
数据映射
筛选排序
视图模式
✅ 无TypeScript错误 ✅ 无Linter警告 ✅ 类型检查通过 ✅ 项目可正常运行
http://localhost:4200/customer-service/project-list
| 字段名 | 类型 | 说明 | 示例值 | 
|---|---|---|---|
| objectId | String | 项目ID | "abc123" | 
| title | String | 项目名称 | "李总别墅设计" | 
| company | Pointer | 所属公司 | → Company | 
| contact | Pointer | 客户信息 | → ContactInfo | 
| assignee | Pointer | 负责设计师 | → Profile | 
| owner | Pointer | 创建人 | → Profile | 
| status | String | 项目状态 | "进行中" | 
| currentStage | String | 当前阶段 | "建模" | 
| deadline | Date | 截止时间 | 2024-12-31 | 
| description | String | 项目描述 | "..." | 
| priority | String | 优先级 | "high" | 
| isDeleted | Boolean | 软删除 | false | 
| createdAt | Date | 创建时间 | 2024-01-01 | 
| updatedAt | Date | 更新时间 | 2024-10-24 | 
本次更新成功完成了客服项目列表的真实数据对接,实现了以下核心目标:
✅ 真实数据显示 - 从Parse Server加载真实项目数据
✅ 四阶段看板 - 按订单分配、确认需求、交付执行、售后分组
✅ 正确映射 - Parse Server字段正确映射到前端模型
✅ 完整功能 - 筛选、排序、搜索、跳转等功能完整
✅ 类型安全 - TypeScript类型检查通过,无编译错误
项目列表现在可以正确显示后端的真实项目数据,并按照业务流程的四个阶段进行组织展示,为客服人员提供了清晰的项目管理视图。
项目现已可以正常编译和运行 ✅