role-function-operation-guide.md 59 KB

客服与管理员功能操作指南

文档概述

本文档详细梳理了客服板块管理员板块的功能模块、操作流程、角色权限和数据字段,为产品复盘和功能优化提供完整的参考依据。


一、客服板块功能体系

1.1 客服工作台首页 (/customer-service/dashboard)

1.1.1 核心数据看板

数据统计卡片(5个核心指标):

指标名称 数据来源 计算逻辑 点击操作
项目总数 Project count() 查询所有项目 跳转到项目列表(显示全部)
新咨询数 Project 今日新增项目数(createdAt >= 今日0点 -
待分配项目 Project currentStage 为订单分配阶段的项目数 跳转到项目列表(筛选待分配)
异常项目 Project 超期项目数(deadline < 当前时间 且状态为进行中) -
售后服务 ProjectFeedback 类型为投诉且状态为待处理的反馈数 -

数据表结构

// Project 表字段
{
  title: string;              // 项目名称
  currentStage: string;       // 当前阶段(订单分配/确认需求/交付执行/售后归档)
  status: string;             // 状态(待分配/进行中/已完成)
  deadline: Date;             // 截止时间
  createdAt: Date;            // 创建时间
  company: Pointer;           // 所属公司
  contact: Pointer;           // 客户信息
  assignee: Pointer;          // 负责人
}

1.1.2 待跟进尾款项目

功能描述:显示处于售后归档阶段且有未付尾款的项目列表

数据来源

  • 查询 Project 表,筛选 currentStage 为售后归档相关阶段
  • Project.data 字段读取支付信息(不使用 ProjectPayment 表)

显示字段

{
  projectName: string;        // 项目名称
  customerName: string;       // 客户姓名
  customerPhone: string;      // 客户电话
  finalPaymentAmount: number; // 剩余未付金额
  totalAmount: number;        // 订单总金额
  paidAmount: number;         // 已付金额
  dueDate: Date;             // 到期日期
  status: string;            // 状态(已逾期/待创建/待付款)
  overdueDay: number;        // 逾期天数
}

操作路径

  1. 点击"开始跟进"按钮
  2. 跳转到项目详情页的售后归档阶段 (/wxwork/:cid/project/:projectId/aftercare)
  3. 查看尾款详情和支付凭证

1.1.3 紧急事件栏

功能描述:自动计算并显示截止时间已到或即将到达但未完成的关键节点

计算逻辑(复用组长端逻辑):

// 紧急事件类型
{
  type: 'review' | 'delivery' | 'deadline';  // 小图对图/交付审批/项目截止
  projectId: string;
  projectName: string;
  deadline: Date;
  urgencyLevel: 'critical' | 'high' | 'medium';
  description: string;
}

紧急程度判断

  • Critical(严重):已逾期
  • High(高):1天内到期
  • Medium(中等):3天内到期

操作路径

  1. 点击紧急事件卡片
  2. 跳转到对应项目的相应阶段

1.1.4 待办任务栏

功能描述:显示从问题板块加载的待办任务(待处理+处理中状态)

数据来源ProjectIssue

数据结构

{
  id: string;
  title: string;              // 问题标题
  description: string;        // 问题描述
  status: '待处理' | '处理中' | '已解决' | '已关闭';
  priority: '紧急' | '高' | '中' | '低';
  projectId: string;
  projectName: string;
  creator: Pointer;           // 创建人
  assignee: Pointer;          // 负责人
  createdAt: Date;
  updatedAt: Date;
}

操作功能

  1. 查看详情:展开问题详细信息
  2. 添加评论:在问题下添加跟进评论
  3. 催办:发送催办通知给负责人
  4. 新建问题:创建新的项目问题

1.2 案例库 (/customer-service/case-library)

1.2.1 案例展示

数据来源Case 表(从已完成项目自动生成)

案例数据结构

{
  id: string;
  name: string;               // 案例名称
  projectId: string;          // 关联项目ID
  projectName: string;        // 项目名称
  designer: string;           // 设计师姓名
  designerId: string;
  team: string;               // 团队名称
  teamId: string;
  coverImage: string;         // 封面图
  images: string[];           // 案例图片
  area: number;               // 面积
  projectType: '工装' | '家装';
  spaceType: '平层' | '复式' | '别墅' | '自建房';
  renderingLevel: '高端' | '中端' | '低端';
  tag: string[];              // 风格标签
  totalPrice: number;         // 项目总额
  completionDate: Date;       // 完成时间
  viewCount: number;          // 浏览次数
  shareCount: number;         // 分享次数
  favoriteCount: number;      // 收藏次数
  isExcellent: boolean;       // 是否优秀案例
  isPublished: boolean;       // 是否发布
}

1.2.2 数据统计功能

统计按钮位置:页面头部右侧(案例总数和本月新增统计卡片旁边)

三大统计维度

  1. Top 5 分享案例

    • 计算逻辑:按 shareCount 降序排序,取前5名
    • 显示:案例名称 + 分享次数
    • 前3名特殊徽章:🥇金、🥈银、🥉铜
  2. 客户最喜欢风格

    • 计算逻辑:统计所有案例的 tag 标签,按 favoriteCount 累加
    • 显示:风格名称 + 收藏次数
    • 取前5个最受欢迎风格
  3. 设计师推荐率

    • 计算逻辑:推荐率 = (优秀案例数 / 总案例数) × 100%
    • 优秀案例:isExcellent = true
    • 显示:设计师姓名 + 推荐率百分比
    • 取前5名设计师

1.2.3 筛选搜索功能

筛选条件

  • 项目案例名称(模糊搜索)
  • 设计师姓名
  • 项目类型(工装/家装)
  • 空间类型(平层/复式/别墅/自建房)
  • 渲染级别(高端/中端/低端)
  • 风格标签
  • 面积范围

分页:每页显示12个案例(3列×4行)


1.3 项目列表 (/customer-service/project-list)

1.3.1 三种视图模式

1. 卡片视图(看板)

  • 按四大阶段分列:订单分配、确认需求、交付执行、售后
  • 每列显示该阶段的项目卡片
  • 卡片信息:项目名称、客户、设计师、截止时间、进度、标签

2. 列表视图

  • 表格形式展示所有项目
  • 支持分页(每页8条)
  • 显示字段:项目名称、客户、设计师、当前阶段、状态、截止时间、操作

3. 监控大盘

  • 嵌入组长端监控大盘(iframe)
  • 隐藏待办任务栏
  • 显示项目甘特图、负载日历等

视图切换

  • 记忆上次选择的视图模式(localStorage)
  • 按钮切换:卡片 | 列表 | 监控大盘

1.3.2 项目数据结构

{
  id: string;
  name: string;               // 项目名称
  customerName: string;       // 客户姓名
  customerId: string;
  assigneeName: string;       // 负责人姓名
  assigneeId: string;
  currentStage: string;       // 当前阶段
  status: string;             // 状态
  deadline: Date;             // 截止时间
  progress: number;           // 进度(0-100)
  daysUntilDeadline: number;  // 距离截止天数
  isUrgent: boolean;          // 是否紧急
  tagDisplayText: string;     // 标签显示文本
  createdAt: Date;
  updatedAt: Date;
}

1.3.3 操作路径

点击项目卡片

  1. 设置 localStorage 标记:enterFromCustomerService = '1'
  2. 跳转到项目详情页:/wxwork/:cid/project/:projectId/:stage
  3. 根据阶段显示对应内容

1.4 需求确认阶段操作流程

1.4.1 参考图片拖拽上传

操作步骤

  1. 展开对应空间(客厅、卧室等)
  2. 将多张参考图片拖拽到"参考图片"区域
  3. 触发AI自动分析归类

AI分析功能

  • 识别图片类型:软装/硬装/CAD/其他
  • 自动分类到对应标签
  • 提取设计元素和风格特征

数据存储

// ProjectFile 表
{
  fileName: string;
  fileUrl: string;
  fileSize: number;
  fileType: string;           // 'image' | 'cad' | 'document'
  category: string;           // 'soft_decor' | 'hard_decor' | 'cad' | 'other'
  projectId: string;
  productId: string;          // 空间ID
  stage: 'requirements';
  uploadedBy: Pointer;
  uploadedAt: Date;
  analysisResult: object;     // AI分析结果
}

1.4.2 需求填写

全局需求

  • 风格偏好(现代简约、北欧、中式等)
  • 色彩方案(主色调、副色调、点缀色、氛围)
  • 预算范围(最低-最高)
  • 工期要求
  • 质量等级(标准/高端/奢华)
  • 特殊需求(文本描述)
  • 环境要求(采光、通风、隔音、温控)

空间需求(按空间分别填写):

  • 功能需求
  • 风格偏好
  • 色彩方案
  • 材质偏好
  • 家具需求
  • 特殊要求

1.4.3 AI生成方案

操作路径

  1. 填写完需求后,点击"AI生成方案"按钮
  2. 调用 AIService.generateDesignSolution()
  3. 使用豆包1.6模型生成设计方案

生成内容

{
  overallStyle: string;       // 整体风格定位
  colorScheme: {
    primary: string;          // 主色调
    secondary: string;        // 副色调
    accent: string;           // 点缀色
  };
  materialRecommendations: string[];  // 材质推荐
  layoutOptimization: string[];       // 布局优化建议
  budgetAssessment: {
    estimatedMin: number;
    estimatedMax: number;
    riskLevel: string;
  };
  timeline: string;           // 预计工期
  riskFactors: string[];      // 风险因素
  spaceSolutions: Array<{     // 各空间方案
    name: string;
    styleDescription: string;
    colorPalette: string[];
    materials: string[];
    furnitureRecommendations: string[];
  }>;
}

1.4.4 设计助手

功能描述:AI聊天助手,回答家装设计相关问题

操作路径

  1. 点击"展开设计助手"
  2. 输入问题(如"客厅应该选择什么颜色?")
  3. AI基于项目需求和分析结果给出专业建议

实现

  • 使用豆包1.6模型
  • 上下文包含:项目需求、AI分析结果、空间信息
  • 回答限制在200字以内

1.4.5 确认需求

操作路径

  1. 确认所有需求无误
  2. 点击"确认需求"按钮
  3. 项目进入下一阶段(交付执行)

1.5 交付执行阶段操作流程

1.5.1 拖拽上传交付文件

操作步骤

  1. 展开对应空间
  2. 将交付图片拖拽到空间区域(不指定具体阶段)
  3. 弹出 drag-upload-modal 组件
  4. AI自动分析图片,识别阶段(白模/软装/渲染/后期)

AI分析服务

  • 服务:ImageAnalysisService
  • 模型:豆包1.6 (fmode-1.6-cn)
  • 分析内容:
    • 图片质量(清晰度、亮度、对比度)
    • 内容识别(类别、置信度、描述、标签)
    • 技术参数(格式、色彩空间、DPI、分辨率)
    • 阶段分类建议

弹窗显示

┌─────────────────────────────────────┐
│  AI智能识别上传弹窗                    │
├─────────────────────────────────────┤
│  文件 │ 名称 │ 上传 │ 空间 │ 阶段    │
├─────────────────────────────────────┤
│  [图] │ xxx.jpg │ 完成 │ 客厅 │ 软装 │
│  [图] │ yyy.png │ 完成 │ 卧室 │ 渲染 │
├─────────────────────────────────────┤
│         [撤回]  [确认交付清单]        │
└─────────────────────────────────────┘

1.5.2 确认交付清单

操作路径

  1. AI分析完成后,点击"确认交付清单"
  2. 文件自动归类到各阶段
  3. 系统记录上传人员身份和时间

记录信息

// Project.data.spaceConfirmations
{
  [spaceId]: {
    confirmedBy: string;        // 确认人ID
    confirmedByName: string;    // 确认人姓名
    confirmedByRole: string;    // 确认人角色
    confirmedAt: Date;          // 确认时间
    filesSnapshot: string[];    // 文件ID快照
  }
}

1.5.3 上传交付清单(提交审批)

操作路径

  1. 所有空间完成确认后
  2. 点击"上传交付清单"按钮
  3. 项目进入待审批状态
  4. 组长端看板显示待审批项目

审批状态记录

// Project.data.deliveryApproval
{
  status: 'pending';          // 待审批
  stage: 'delivery';
  totalFiles: number;
  types: {                    // 各类型文件数量
    white_model: number;
    soft_decor: number;
    rendering: number;
    post_process: number;
  };
  submittedAt: Date;
  submittedByName: string;
  submittedById: string;
}

1.6 售后归档阶段操作流程

1.6.1 上传支付凭证

操作步骤

  1. 点击"上传支付凭证"按钮
  2. 选择支付凭证图片
  3. AI自动提取支付金额

AI提取逻辑

  • 识别支付凭证中的金额数字
  • 自动填充到支付金额字段
  • 支持手动修改

数据存储

// Project.data.payments
{
  voucherUrl: string;         // 凭证图片URL
  amount: number;             // 支付金额
  extractedAmount: number;    // AI提取的金额
  uploadedBy: string;
  uploadedAt: Date;
  type: 'deposit' | 'progress' | 'final';  // 定金/进度款/尾款
}

1.6.2 预览支付凭证

功能描述:点击凭证图片可放大预览

显示信息

  • 凭证图片
  • 支付金额
  • 上传时间
  • 上传人

1.6.3 总金额计算

默认值:报价总金额(从订单分配阶段获取)

计算逻辑

totalAmount = 报价总金额;
paidAmount = sum(所有支付凭证金额);
remainingAmount = totalAmount - paidAmount;

二、管理员板块功能体系

2.1 管理员后台总览看板 (/admin/dashboard)

2.1.1 核心统计数据

6大核心指标

指标名称 数据来源 计算逻辑 点击操作
总项目数 Project count() 所有项目 展开项目明细面板
进行中项目 Project 根据 currentStage 自动判断状态为"进行中" 展开进行中项目明细
已完成项目 Project currentStage 为售后归档阶段自动标记为已完成 展开已完成项目明细
设计师总数 Profile roleName = '组员' 的员工数 展开设计师明细
客户总数 ContactInfo count() 所有客户 展开客户明细
总收入 Project.data 从售后归档项目中累加已支付尾款 展开收入明细

状态自动判断逻辑

function getProjectStatusByStage(stageId: string, currentStatus?: string): string {
  // 如果已经是完成或取消状态,保持不变
  if (currentStatus === '已完成' || currentStatus === '已取消') {
    return currentStatus;
  }
  
  const corePhase = mapStageToCorePhase(stageId);
  
  switch (corePhase) {
    case 'order':
      return '待分配';
    case 'requirements':
    case 'delivery':
      return '进行中';
    case 'aftercare':
      return '已完成';  // 售后归档自动标记为已完成
    default:
      return '待分配';
  }
}

2.1.2 数据可视化图表

1. 项目趋势图(ECharts折线图)

  • X轴:月份
  • Y轴:项目数量
  • 数据:每月新增项目数

2. 收入趋势图(ECharts柱状图)

  • X轴:月份
  • Y轴:收入金额
  • 数据:每月收入统计

2.1.3 明细面板

点击统计卡片后展开侧边抽屉,显示详细数据:

项目明细

  • 项目列表(表格)
  • 筛选:关键词、状态、日期范围
  • 排序:创建时间、更新时间
  • 分页:每页10条

设计师明细

  • 设计师列表
  • 显示:姓名、职级、完成项目数、进行中项目数、平均周期
  • 筛选:关键词、职级

客户明细

  • 客户列表
  • 显示:姓名、手机号、来源、创建时间
  • 筛选:关键词、来源

2.2 项目管理 (/admin/project-management)

2.2.1 项目列表展示

数据查询

// 查询逻辑
const projects = await ProjectService.findProjects({
  status: statusFilter,      // 状态筛选
  keyword: searchTerm,       // 关键词搜索
  skip: currentPage * pageSize,
  limit: pageSize
});

// Include关联数据
include: ['contact', 'customer', 'assignee', 'department', 'department.leader']

显示字段

  • 项目名称
  • 客户姓名
  • 负责人(优先从 assignee,其次从 ProjectTeam 表获取)
  • 当前阶段(规范化为四大核心阶段)
  • 状态(自动判断)
  • 创建时间
  • 更新时间

2.2.2 项目详情预览

操作路径

  1. 右键点击项目行
  2. 选择"预览详情"
  3. 弹出详情面板

显示内容

  • 基本信息:项目名称、客户、负责人、状态、阶段
  • 时间信息:创建时间、更新时间、截止时间
  • 团队信息:项目组、团队成员
  • 进度信息:当前进度、完成情况

2.2.3 分配设计师

操作路径

  1. 点击项目行的"分配设计师"按钮
  2. 弹出设计师分配弹窗
  3. 选择主要负责人和协作成员
  4. 保存分配

分配逻辑

// 更新 Project.assignee(主要负责人)
project.set('assignee', {
  __type: 'Pointer',
  className: 'Profile',
  objectId: mainDesignerId
});

// 保存所有分配的设计师到 Project.data
project.set('data', {
  ...data,
  assignedDesigners: [designerId1, designerId2, ...],
  crossTeamCollaborators: [...],
  primaryTeamId: teamId
});

// 创建 ProjectTeam 记录
const projectTeam = new ProjectTeam();
projectTeam.set('project', project.toPointer());
projectTeam.set('profile', designer.toPointer());
projectTeam.set('role', 'primary' | 'collaborator');
await projectTeam.save();

2.2.4 筛选和排序

筛选条件

  • 状态:全部/待分配/进行中/已完成
  • 关键词:项目名称模糊搜索

排序字段

  • 创建时间
  • 更新时间
  • 项目名称

分页:每页10条


2.3 项目组管理 (/admin/departments)

2.3.1 项目组列表

数据来源Department

数据结构

{
  id: string;
  name: string;               // 项目组名称
  leader: Pointer;            // 组长(Profile)
  leaderName: string;         // 组长姓名
  type: 'project';            // 类型
  memberCount: number;        // 成员数量
  createdAt: Date;
  isDeleted: boolean;
}

显示字段

  • 项目组名称
  • 组长姓名
  • 成员数量
  • 创建时间
  • 操作按钮

2.3.2 新建项目组

操作路径

  1. 点击"新建项目组"按钮
  2. 填写项目组名称
  3. 选择组长(从员工列表选择,roleName = '组长'
  4. 保存

创建逻辑

const dept = await DepartmentService.createDepartment({
  name: '设计一组',
  leaderId: 'profileId',
  type: 'project'
});

// 同时更新组长的 department 字段
const profile = await Parse.Query('Profile').get(leaderId);
profile.set('department', dept.toPointer());
await profile.save();

2.3.3 编辑项目组

可编辑字段

  • 项目组名称
  • 组长

操作路径

  1. 点击"编辑"按钮
  2. 修改信息
  3. 保存

2.3.4 删除项目组

删除方式:软删除(设置 isDeleted = true

操作路径

  1. 点击"删除"按钮
  2. 确认删除
  3. 执行软删除

注意事项

  • 删除前检查是否有关联项目
  • 如有关联项目,提示先解除关联

2.3.5 查看成员

操作路径

  1. 点击项目组行
  2. 展开成员列表

显示内容

  • 成员姓名
  • 角色(组长/组员)
  • 手机号
  • 状态

2.4 员工管理 (/admin/employees)

2.4.1 员工列表

数据来源Profile 表(从企微同步)

数据结构

{
  id: string;
  name: string;               // 昵称(内部沟通用)
  realname: string;           // 真实姓名
  mobile: string;             // 手机号
  userid: string;             // 企微ID
  roleName: string;           // 身份(组长/组员/客服/管理员)
  department: Pointer;        // 所属部门
  departmentName: string;     // 部门名称
  isDisabled: boolean;        // 是否禁用
  avatar: string;             // 头像
  email: string;              // 邮箱
  position: string;           // 职位
  gender: string;             // 性别
  level: string;              // 职级
  skills: string[];           // 技能标签
  joinDate: Date;             // 入职日期
  createdAt: Date;
}

显示字段

  • 姓名(真实姓名 + 昵称)
  • 手机号
  • 企微ID
  • 身份
  • 部门
  • 状态(正常/已禁用)

2.4.2 查看详情

操作路径

  1. 点击"查看"按钮
  2. 打开员工信息侧边栏

侧边栏包含两个标签页

1. 基本信息标签页

  • 员工头像、姓名、职位
  • 联系方式(手机、邮箱、企微ID)
  • 组织信息(身份、部门、职级)
  • 技能标签
  • 工作量统计(当前项目数、已完成项目数、平均质量)

2. 项目负载标签页

  • 负载概况(当前项目数、核心项目列表)
  • 负载详细日历(月视图、项目数量可视化)
  • 请假明细(未来7天)
  • 红色标记说明
  • 能力问卷展示
  • 详细工作日历

2.4.3 任务安排

查看员工任务

  • 当前负责的项目列表
  • 项目名称、阶段、截止时间、优先级
  • 任务状态(进行中/已完成/逾期)

数据来源

// 查询员工负责的项目
const projects = await Parse.Query('Project')
  .equalTo('assignee', employeeId)
  .equalTo('status', '进行中')
  .find();

// 或从 ProjectTeam 表查询
const teams = await Parse.Query('ProjectTeam')
  .equalTo('profile', employeeId)
  .include('project')
  .find();

2.4.4 编辑信息

可编辑字段

  • 昵称(name)
  • 真实姓名(realname)
  • 手机号(mobile)
  • 身份(roleName)
  • 部门(department)
  • 状态(isDisabled)

不可编辑字段

  • 企微ID(userid)- 只读显示
  • 创建时间

操作路径

  1. 点击"编辑"按钮
  2. 修改可编辑字段
  3. 保存

保存逻辑

await EmployeeService.updateEmployee(employeeId, {
  name: formData.name,
  mobile: formData.mobile,
  roleName: formData.roleName,
  departmentId: formData.departmentId,
  isDisabled: formData.isDisabled,
  data: {
    realname: formData.realname
  }
});

2.4.5 禁用/启用员工

操作路径

  1. 点击"禁用"或"启用"按钮
  2. 确认操作
  3. 更新 isDisabled 字段

影响

  • 禁用后员工无法登录系统
  • 已分配的项目不受影响

2.5 客户管理 (/admin/customers)

2.5.1 客户列表

数据来源ContactInfo

数据结构

{
  id: string;
  name: string;               // 客户姓名
  mobile: string;             // 手机号
  external_userid: string;    // 企微外部联系人ID
  source: string;             // 来源(企微/电话/网站等)
  type: string;               // 类型(企业成员/外部联系人)
  avatar: string;             // 头像
  createdAt: Date;
  data: {
    avatar: string;
    name: string;
    // 其他扩展字段
  };
}

显示字段

  • 客户名称
  • 手机号
  • 企微ID
  • 类型
  • 来源
  • 创建时间

2.5.2 查看客户详情

操作路径

  1. 点击客户行
  2. 打开客户详情面板

详情面板包含

1. 基本信息卡片

  • 客户头像
  • 姓名
  • 手机号
  • 企微ID
  • 客户类型
  • 来源

2. 关联项目

  • 项目列表(该客户的所有项目)
  • 项目名称、状态、阶段、更新时间
  • 点击可跳转到项目详情

3. 所在群聊

  • 客户所在的企微群聊列表
  • 群聊名称、关联项目、成员数
  • 点击可跳转到群聊详情

4. 跟进记录

  • 活动日志(ActivityLog 表)
  • 操作人、操作类型、操作时间、备注
  • 按时间倒序排列

数据查询逻辑

// 查询客户项目
const projects = await Parse.Query('Project')
  .equalTo('contact', customerId)
  .include('assignee')
  .find();

// 查询客户群聊
const groupContacts = await Parse.Query('GroupChatContact')
  .equalTo('userid', customer.get('external_userid'))
  .include('groupChat')
  .include('groupChat.project')
  .find();

// 查询跟进记录
const followUps = await Parse.Query('ActivityLog')
  .equalTo('entityId', customerId)
  .equalTo('module', 'customer')
  .include('actor')
  .descending('createdAt')
  .find();

2.6 群组管理 (/admin/groupchats)

2.6.1 群组列表

数据来源GroupChat

数据结构

{
  id: string;
  chat_id: string;            // 企微群ID
  name: string;               // 群名称
  project: Pointer;           // 关联项目
  memberCount: number;        // 成员数量
  isDisabled: boolean;        // 是否禁用
  member_list: Array<{        // 成员列表
    userid: string;
    type: number;             // 1=企业成员, 2=外部联系人
    join_time: number;
  }>;
  createdAt: Date;
}

显示字段

  • 群名称
  • 企微群ID
  • 关联项目
  • 成员数
  • 状态
  • 操作按钮

2.6.2 统计企微群聊

统计维度

  • 总群聊数
  • 已关联项目的群聊数
  • 未关联项目的群聊数
  • 平均成员数

筛选条件

  • 关键词搜索(群名称)
  • 是否关联项目

2.6.3 关联项目

操作路径

  1. 点击未关联项目的群聊
  2. 选择"关联项目"或"创建项目"

关联现有项目

const groupChat = await Parse.Query('GroupChat').get(groupChatId);
groupChat.set('project', project.toPointer());
await groupChat.save();

// 创建 ProjectGroup 关联(支持多项目多群)
const projectGroup = new ProjectGroup();
projectGroup.set('project', project.toPointer());
projectGroup.set('groupChat', groupChat.toPointer());
projectGroup.set('isPrimary', true);
await projectGroup.save();

创建新项目

// 1. 创建项目
const project = new Project();
project.set('title', projectName);
project.set('company', company.toPointer());
project.set('status', '待分配');
project.set('currentStage', '订单分配');
project.set('data', {
  createdBy: 'admin',
  createdFrom: 'admin_groupchat',
  groupChatId: groupChatId
});
await project.save();

// 2. 关联群聊
groupChat.set('project', project.toPointer());
await groupChat.save();

// 3. 创建 ProjectGroup
const projectGroup = new ProjectGroup();
projectGroup.set('project', project.toPointer());
projectGroup.set('groupChat', groupChat.toPointer());
projectGroup.set('isPrimary', true);
await projectGroup.save();

2.6.4 查看群聊详情

操作路径

  1. 点击群聊行
  2. 打开群聊详情面板

详情内容

  • 群名称
  • 企微群ID
  • 成员列表(姓名、类型、加入时间)
  • 关联项目信息
  • 入群二维码(如有)

数据来源

// 从企微API获取群聊详情
const chatInfo = await WxworkCorp.externalContact.groupChat.get(chat_id);

2.6.5 修改群聊信息

可修改字段

  • 关联项目
  • 是否禁用

操作路径

  1. 点击"编辑"按钮
  2. 修改信息
  3. 保存

三、数据字段汇总

3.1 核心数据表

Project(项目表)

{
  objectId: string;
  title: string;              // 项目名称
  company: Pointer<Company>;
  contact: Pointer<ContactInfo>;  // 客户
  assignee: Pointer<Profile>;     // 负责人
  department: Pointer<Department>; // 项目组
  status: string;             // 状态(待分配/进行中/已完成/已取消)
  currentStage: string;       // 当前阶段
  deadline: Date;             // 截止时间
  createdAt: Date;
  updatedAt: Date;
  isDeleted: boolean;
  data: {
    // 订单分配阶段
    orderApproval: object;    // 订单审批信息
    quotation: object;        // 报价信息
    
    // 需求确认阶段
    requirements: object;     // 需求信息
    aiAnalysis: object;       // AI分析结果
    
    // 交付执行阶段
    deliveryApproval: object; // 交付审批信息
    deliveryStageStatus: object; // 各阶段状态
    spaceConfirmations: object;  // 空间确认记录
    
    // 售后归档阶段
    payments: array;          // 支付记录
    totalAmount: number;      // 总金额
    paidAmount: number;       // 已付金额
    
    // 其他
    assignedDesigners: string[]; // 分配的设计师
    crossTeamCollaborators: string[]; // 跨组协作者
    primaryTeamId: string;    // 主要团队ID
  };
}

Profile(员工表)

{
  objectId: string;
  name: string;               // 昵称
  mobile: string;
  userid: string;             // 企微ID
  roleName: string;           // 身份
  department: Pointer<Department>;
  company: Pointer<Company>;
  isDeleted: boolean;
  createdAt: Date;
  data: {
    realname: string;         // 真实姓名
    avatar: string;
    email: string;
    position: string;
    gender: string;
    level: string;
    skills: string[];
  };
}

ContactInfo(客户表)

{
  objectId: string;
  name: string;
  mobile: string;
  external_userid: string;    // 企微外部联系人ID
  source: string;             // 来源
  company: Pointer<Company>;
  isDeleted: boolean;
  createdAt: Date;
  data: {
    avatar: string;
    name: string;
    type: string;
  };
}

Department(部门/项目组表)

{
  objectId: string;
  name: string;
  leader: Pointer<Profile>;
  type: string;               // 'project'
  company: Pointer<Company>;
  isDeleted: boolean;
  createdAt: Date;
  data: object;
}

GroupChat(群聊表)

{
  objectId: string;
  chat_id: string;            // 企微群ID
  name: string;
  project: Pointer<Project>;
  company: Pointer<Company>;
  isDisabled: boolean;
  member_list: array;
  createdAt: Date;
}

Case(案例表)

{
  objectId: string;
  name: string;
  projectId: string;
  projectName: string;
  designer: string;
  designerId: string;
  team: string;
  teamId: string;
  coverImage: string;
  images: string[];
  area: number;
  projectType: string;
  spaceType: string;
  renderingLevel: string;
  tag: string[];
  totalPrice: number;
  completionDate: Date;
  viewCount: number;
  shareCount: number;
  favoriteCount: number;
  isExcellent: boolean;
  isPublished: boolean;
  company: Pointer<Company>;
  isDeleted: boolean;
  createdAt: Date;
}

ProjectIssue(项目问题表)

{
  objectId: string;
  title: string;
  description: string;
  status: string;             // 待处理/处理中/已解决/已关闭
  priority: string;           // 紧急/高/中/低
  project: Pointer<Project>;
  creator: Pointer<Profile>;
  assignee: Pointer<Profile>;
  company: Pointer<Company>;
  isDeleted: boolean;
  createdAt: Date;
  updatedAt: Date;
}

ProjectFile(项目文件表)

{
  objectId: string;
  fileName: string;
  fileUrl: string;
  fileSize: number;
  fileType: string;
  category: string;
  project: Pointer<Project>;
  product: Pointer<Product>;  // 空间
  stage: string;              // 阶段
  uploadedBy: Pointer<Profile>;
  uploadedAt: Date;
  analysisResult: object;     // AI分析结果
  approvalStatus: string;     // 审批状态
  company: Pointer<Company>;
  isDeleted: boolean;
}

四、操作路径总结

4.1 客服操作路径

客服工作台首页
├── 查看项目总数 → 跳转项目列表(全部)
├── 查看待分配项目 → 跳转项目列表(筛选待分配)
├── 待跟进尾款项目
│   └── 点击"开始跟进" → 跳转项目详情(售后归档阶段)
├── 紧急事件
│   └── 点击事件卡片 → 跳转对应项目阶段
└── 待办任务
    ├── 查看详情 → 展开问题详情
    ├── 添加评论 → 在问题下评论
    ├── 催办 → 发送催办通知
    └── 新建问题 → 创建项目问题

案例库
├── 浏览案例 → 查看案例详情
├── 点击数据统计 → 展开统计面板
│   ├── Top 5 分享案例
│   ├── 客户最喜欢风格
│   └── 设计师推荐率
└── 筛选搜索 → 按条件筛选案例

项目列表
├── 切换视图模式
│   ├── 卡片视图(看板)
│   ├── 列表视图
│   └── 监控大盘
├── 点击项目卡片 → 跳转项目详情
└── 筛选排序 → 按条件筛选项目

需求确认阶段
├── 拖拽参考图片 → AI自动分析归类
├── 填写需求信息
│   ├── 全局需求
│   └── 空间需求
├── 点击AI生成方案 → 生成设计方案
├── 展开设计助手 → AI聊天助手
└── 确认需求 → 进入下一阶段

交付执行阶段
├── 拖拽交付图片 → 弹出AI分析弹窗
├── AI自动识别阶段 → 显示分析结果
├── 确认交付清单 → 文件归类到各阶段
└── 上传交付清单 → 提交审批

售后归档阶段
├── 上传支付凭证 → AI提取金额
├── 预览支付凭证 → 放大查看
└── 查看尾款详情 → 显示支付记录

4.2 管理员操作路径

管理员后台总览
├── 点击统计卡片 → 展开明细面板
│   ├── 总项目数 → 项目明细
│   ├── 进行中项目 → 进行中项目明细
│   ├── 已完成项目 → 已完成项目明细
│   ├── 设计师总数 → 设计师明细
│   ├── 客户总数 → 客户明细
│   └── 总收入 → 收入明细
└── 查看图表 → 项目趋势图、收入趋势图

项目管理
├── 查看项目列表 → 表格展示
├── 右键预览详情 → 弹出详情面板
├── 分配设计师 → 打开分配弹窗
│   ├── 选择主要负责人
│   ├── 选择协作成员
│   └── 保存分配
├── 筛选排序 → 按条件筛选
└── 跳转项目详情 → 查看完整信息

项目组管理
├── 查看项目组列表
├── 新建项目组
│   ├── 填写名称
│   ├── 选择组长
│   └── 保存
├── 编辑项目组
│   ├── 修改名称
│   ├── 更换组长
│   └── 保存
├── 删除项目组 → 软删除
└── 查看成员 → 展开成员列表

员工管理
├── 查看员工列表
├── 查看详情 → 打开员工信息侧边栏
│   ├── 基本信息标签页
│   └── 项目负载标签页
├── 查看任务安排 → 显示负责的项目
├── 编辑信息
│   ├── 修改可编辑字段
│   └── 保存
└── 禁用/启用员工 → 更新状态

客户管理
├── 查看客户列表
├── 点击客户 → 打开详情面板
│   ├── 基本信息
│   ├── 关联项目
│   ├── 所在群聊
│   └── 跟进记录
└── 筛选搜索 → 按条件筛选

群组管理
├── 查看群组列表
├── 统计企微群聊 → 显示统计数据
├── 关联项目
│   ├── 关联现有项目
│   └── 创建新项目
├── 查看群聊详情 → 打开详情面板
│   ├── 群信息
│   ├── 成员列表
│   └── 关联项目
└── 修改群聊信息 → 编辑保存

五、可计算分析的数据指标

5.1 项目维度

项目统计

  • 总项目数
  • 各阶段项目数(订单分配/确认需求/交付执行/售后归档)
  • 各状态项目数(待分配/进行中/已完成/已取消)
  • 平均项目周期
  • 项目完成率 = 已完成项目数 / 总项目数
  • 项目逾期率 = 逾期项目数 / 总项目数

时间分析

  • 每月新增项目数
  • 每月完成项目数
  • 各阶段平均停留时间
  • 项目平均周期趋势

客户分析

  • 客户项目数分布
  • 客户复购率
  • 客户满意度(从反馈表)

5.2 设计师维度

工作量统计

  • 当前负责项目数
  • 已完成项目数
  • 平均项目周期
  • 负载率 = 当前项目数 / 标准负载

绩效分析

  • 项目完成率
  • 项目逾期率
  • 客户满意度
  • 优秀案例数
  • 推荐率 = 优秀案例数 / 总案例数

能力评估

  • 擅长风格(从案例标签统计)
  • 擅长空间类型
  • 平均项目金额

5.3 案例维度

案例统计

  • 总案例数
  • 各风格案例数
  • 各空间类型案例数
  • 各渲染级别案例数
  • 平均浏览量
  • 平均分享量
  • 平均收藏量

热门分析

  • Top 5 分享案例
  • Top 5 收藏案例
  • 最受欢迎风格(按收藏数)
  • 最受欢迎空间类型

设计师分析

  • 各设计师案例数
  • 各设计师推荐率
  • 各设计师平均浏览量

5.4 财务维度

收入统计

  • 总收入(已支付尾款累加)
  • 每月收入
  • 平均项目金额
  • 收入增长率

回款分析

  • 总应收金额
  • 已收金额
  • 未收金额
  • 回款率 = 已收金额 / 总应收金额
  • 逾期未收金额

项目金额分布

  • 各金额区间项目数
  • 平均项目金额趋势

5.5 问题维度

问题统计

  • 总问题数
  • 各状态问题数(待处理/处理中/已解决/已关闭)
  • 各优先级问题数
  • 平均解决时间
  • 问题解决率

问题分析

  • 各阶段问题数分布
  • 各类型问题数分布
  • 问题高发项目
  • 问题高发设计师

六、总结

本文档详细梳理了客服板块和管理员板块的所有功能模块、操作流程、数据字段和计算逻辑。主要特点:

  1. 客服板块:以项目全生命周期管理为核心,提供工作台首页、案例库、项目列表、需求确认、交付执行、售后归档等完整功能
  2. 管理员板块:以数据统计和资源管理为核心,提供总览看板、项目管理、项目组管理、员工管理、客户管理、群组管理等功能
  3. 数据驱动:所有功能都基于Parse Server数据库,数据结构清晰,关联关系明确
  4. AI赋能:在需求确认和交付执行阶段集成AI分析功能,提升工作效率
  5. 角色权限:不同角色有不同的操作权限和视图

本文档可作为产品复盘、功能优化、培训教材的重要参考资料。


七、角色权限矩阵

7.1 功能权限对照表

功能模块 客服 组长 设计师 管理员
工作台首页
项目列表
案例库
订单分配 ✅审批
需求确认
交付执行 ✅审批
售后归档
项目管理
项目组管理
员工管理
客户管理
群组管理
分配设计师
审批订单
审批交付

7.2 数据权限

客服

  • 查看:所有项目
  • 编辑:自己创建的项目
  • 删除:❌

组长

  • 查看:所有项目
  • 编辑:所有项目
  • 删除:❌
  • 审批:订单分配、交付执行

设计师

  • 查看:自己负责的项目
  • 编辑:自己负责的项目
  • 删除:❌

管理员

  • 查看:所有数据
  • 编辑:所有数据
  • 删除:软删除所有数据
  • 审批:所有审批

八、业务流程图

8.1 客服完整工作流程

graph TD
    A[客服登录系统] --> B[查看工作台首页]
    B --> C{选择工作内容}

    C -->|处理新咨询| D[创建新项目]
    D --> E[填写客户信息]
    E --> F[填写项目基本信息]
    F --> G[提交订单分配]
    G --> H[等待组长审批]

    C -->|跟进尾款| I[查看待跟进尾款列表]
    I --> J[点击开始跟进]
    J --> K[进入售后归档阶段]
    K --> L[查看尾款详情]
    L --> M[联系客户催款]

    C -->|处理紧急事件| N[查看紧急事件列表]
    N --> O[点击紧急事件]
    O --> P[进入对应项目阶段]
    P --> Q[处理紧急事项]

    C -->|处理待办任务| R[查看待办任务列表]
    R --> S[点击任务详情]
    S --> T{任务类型}
    T -->|添加评论| U[输入评论内容]
    T -->|催办| V[发送催办通知]
    T -->|新建问题| W[创建项目问题]

    H --> X{审批结果}
    X -->|通过| Y[进入需求确认阶段]
    X -->|驳回| Z[修改订单信息]
    Z --> G

    Y --> AA[填写需求信息]
    AA --> AB[拖拽参考图片]
    AB --> AC[AI自动分析]
    AC --> AD[点击AI生成方案]
    AD --> AE[确认需求]
    AE --> AF[进入交付执行阶段]

8.2 管理员项目管理流程

graph TD
    A[管理员登录系统] --> B[查看总览看板]
    B --> C[查看统计数据]
    C --> D{选择管理内容}

    D -->|项目管理| E[进入项目管理页面]
    E --> F[查看项目列表]
    F --> G{项目操作}
    G -->|预览详情| H[打开详情面板]
    G -->|分配设计师| I[打开分配弹窗]
    I --> J[选择主要负责人]
    J --> K[选择协作成员]
    K --> L[保存分配]
    L --> M[更新项目信息]

    D -->|项目组管理| N[进入项目组管理]
    N --> O{项目组操作}
    O -->|新建| P[填写项目组信息]
    P --> Q[选择组长]
    Q --> R[保存项目组]
    O -->|编辑| S[修改项目组信息]
    S --> T[保存修改]
    O -->|删除| U[确认删除]
    U --> V[软删除项目组]

    D -->|员工管理| W[进入员工管理]
    W --> X{员工操作}
    X -->|查看详情| Y[打开员工信息面板]
    Y --> Z[查看基本信息]
    Y --> AA[查看项目负载]
    X -->|编辑信息| AB[修改员工信息]
    AB --> AC[保存修改]
    X -->|禁用/启用| AD[更新员工状态]

    D -->|客户管理| AE[进入客户管理]
    AE --> AF[查看客户列表]
    AF --> AG[点击客户]
    AG --> AH[查看客户详情]
    AH --> AI[查看关联项目]
    AH --> AJ[查看所在群聊]
    AH --> AK[查看跟进记录]

    D -->|群组管理| AL[进入群组管理]
    AL --> AM[查看群组列表]
    AM --> AN{群组操作}
    AN -->|关联项目| AO[选择现有项目]
    AN -->|创建项目| AP[填写项目信息]
    AP --> AQ[保存新项目]
    AQ --> AR[关联群聊]
    AN -->|查看详情| AS[打开群聊详情]
    AS --> AT[查看成员列表]

8.3 项目生命周期流程

graph LR
    A[订单分配] --> B{组长审批}
    B -->|通过| C[确认需求]
    B -->|驳回| A

    C --> D[填写需求]
    D --> E[AI生成方案]
    E --> F[确认需求]
    F --> G[交付执行]

    G --> H[白模阶段]
    H --> I[软装阶段]
    I --> J[渲染阶段]
    J --> K[后期阶段]

    K --> L[上传交付清单]
    L --> M{组长审批}
    M -->|通过| N[售后归档]
    M -->|驳回| G

    N --> O[上传支付凭证]
    O --> P[确认尾款]
    P --> Q[项目完成]

九、数据流转图

9.1 项目数据流转

客服创建项目
    ↓
Project表(status: 待分配, currentStage: 订单分配)
    ↓
组长审批
    ↓
Project.data.orderApproval(status: approved)
    ↓
自动更新 Project(status: 进行中, currentStage: 确认需求)
    ↓
客服填写需求
    ↓
Project.data.requirements
    ↓
AI生成方案
    ↓
Project.data.aiAnalysis
    ↓
确认需求
    ↓
Project(currentStage: 交付执行)
    ↓
设计师上传文件
    ↓
ProjectFile表(stage: white_model/soft_decor/rendering/post_process)
    ↓
AI分析文件
    ↓
ProjectFile.analysisResult
    ↓
客服确认空间
    ↓
Project.data.spaceConfirmations
    ↓
上传交付清单
    ↓
Project.data.deliveryApproval(status: pending)
    ↓
组长审批
    ↓
Project.data.deliveryApproval(status: approved)
    ↓
自动更新 Project(currentStage: 售后归档)
    ↓
客服上传支付凭证
    ↓
Project.data.payments
    ↓
AI提取金额
    ↓
更新 Project.data.paidAmount
    ↓
确认尾款
    ↓
Project(status: 已完成)
    ↓
自动生成案例
    ↓
Case表(isPublished: false)

9.2 设计师分配数据流转

管理员/组长分配设计师
    ↓
选择主要负责人
    ↓
Project.assignee = Pointer<Profile>
    ↓
选择协作成员
    ↓
Project.data.assignedDesigners = [id1, id2, ...]
    ↓
创建 ProjectTeam 记录
    ↓
ProjectTeam(project, profile, role: primary/collaborator)
    ↓
设计师可见项目
    ↓
设计师工作台显示项目

9.3 群聊关联项目数据流转

管理员查看群组列表
    ↓
选择未关联项目的群聊
    ↓
创建新项目 或 关联现有项目
    ↓
Project表(新建或更新)
    ↓
GroupChat.project = Pointer<Project>
    ↓
创建 ProjectGroup 记录
    ↓
ProjectGroup(project, groupChat, isPrimary: true)
    ↓
群聊成员可见项目
    ↓
企微群聊中显示项目卡片

十、关键技术实现

10.1 AI图像分析

服务ImageAnalysisService

模型:豆包1.6 (fmode-1.6-cn)

分析流程

1. 接收图片文件
2. 转换为Base64编码
3. 调用豆包API
4. 解析返回结果
5. 提取关键信息:
   - 图片质量(清晰度、亮度、对比度)
   - 内容识别(类别、置信度、描述、标签)
   - 技术参数(格式、色彩空间、DPI、分辨率)
   - 阶段分类建议(white_model/soft_decor/rendering/post_process)
6. 返回分析结果

应用场景

  • 需求确认阶段:参考图片分类
  • 交付执行阶段:交付文件阶段识别
  • 售后归档阶段:支付凭证金额提取

10.2 项目状态自动判断

核心函数getProjectStatusByStage()

判断逻辑

function getProjectStatusByStage(stageId: string, currentStatus?: string): string {
  // 如果已经是完成或取消状态,保持不变
  if (currentStatus === '已完成' || currentStatus === '已取消') {
    return currentStatus;
  }

  const corePhase = mapStageToCorePhase(stageId);

  switch (corePhase) {
    case 'order':
      return '待分配';
    case 'requirements':
    case 'delivery':
      return '进行中';
    case 'aftercare':
      return '已完成';
    default:
      return '待分配';
  }
}

应用场景

  • 客服端项目列表
  • 组长端监控大盘
  • 管理员端项目管理
  • 统计数据计算

10.3 拖拽上传

技术:HTML5 Drag and Drop API

实现步骤

1. 监听 dragover 事件
   - event.preventDefault()
   - event.dataTransfer.dropEffect = 'move'
   - 显示拖拽提示

2. 监听 dragleave 事件
   - 隐藏拖拽提示

3. 监听 drop 事件
   - event.preventDefault()
   - 获取文件列表:event.dataTransfer.files
   - 过滤文件类型(只允许图片)
   - 打开上传弹窗

4. 自动触发AI分析
   - 延迟500ms
   - 遍历文件列表
   - 调用 ImageAnalysisService.analyzeImage()
   - 显示分析结果

5. 确认上传
   - 批量上传文件到服务器
   - 保存文件记录到 ProjectFile 表
   - 更新项目数据

10.4 审批流程

数据结构

// 订单审批
Project.data.orderApproval = {
  status: 'pending' | 'approved' | 'rejected';
  submittedAt: Date;
  submittedBy: string;
  submittedByName: string;
  approvedAt?: Date;
  approvedBy?: string;
  approvedByName?: string;
  rejectedAt?: Date;
  rejectedBy?: string;
  rejectedByName?: string;
  rejectionReason?: string;
};

// 交付审批
Project.data.deliveryApproval = {
  status: 'pending' | 'approved' | 'rejected';
  stage: 'delivery';
  totalFiles: number;
  types: {
    white_model: number;
    soft_decor: number;
    rendering: number;
    post_process: number;
  };
  submittedAt: Date;
  submittedByName: string;
  submittedById: string;
  approvedAt?: Date;
  approvedBy?: string;
  approvedByName?: string;
  rejectedAt?: Date;
  rejectedBy?: string;
  rejectedByName?: string;
  rejectionReason?: string;
};

审批流程

1. 提交审批
   - 设置 status = 'pending'
   - 记录提交人和时间
   - 通知组长

2. 组长审批
   - 查看审批详情
   - 选择通过或驳回
   - 填写驳回原因(如驳回)
   - 保存审批结果

3. 审批通过
   - 设置 status = 'approved'
   - 记录审批人和时间
   - 自动更新项目阶段
   - 通知提交人

4. 审批驳回
   - 设置 status = 'rejected'
   - 记录驳回人、时间和原因
   - 通知提交人
   - 项目回退到上一阶段

十一、常见问题与解决方案

11.1 数据一致性问题

问题:项目负责人显示不一致

原因

  • Project.assignee 字段为空
  • ProjectTeam 表中有主要负责人记录

解决方案

// 优先从 assignee 获取,其次从 ProjectTeam 获取
let assigneeName = project.get('assignee')?.get('name');
if (!assigneeName || assigneeName === '未分配') {
  const primaryDesigner = await getPrimaryDesignerFromProjectTeam(projectId);
  if (primaryDesigner) {
    assigneeName = primaryDesigner.name;
  }
}

11.2 状态判断不准确

问题:项目状态与实际阶段不符

原因

  • 手动设置的 status 字段未更新
  • 阶段变更后状态未同步

解决方案

// 使用自动判断函数,而不是直接读取 status 字段
const autoStatus = getProjectStatusByStage(currentStage, status);

11.3 文件上传失败

问题:拖拽上传后文件未保存

原因

  • 文件大小超限
  • 网络超时
  • 权限不足

解决方案

// 1. 检查文件大小
if (file.size > 10 * 1024 * 1024) {
  alert('文件大小不能超过10MB');
  return;
}

// 2. 添加重试机制
async function uploadWithRetry(file, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await uploadFile(file);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await sleep(1000 * (i + 1));
    }
  }
}

// 3. 检查权限
const currentUser = Parse.User.current();
if (!currentUser) {
  alert('请先登录');
  return;
}

11.4 AI分析超时

问题:AI分析长时间无响应

原因

  • 图片过大
  • API调用超时
  • 网络问题

解决方案

// 1. 压缩图片
async function compressImage(file) {
  if (file.size > 2 * 1024 * 1024) {
    // 压缩到2MB以下
    return await imageCompression(file, {
      maxSizeMB: 2,
      maxWidthOrHeight: 1920
    });
  }
  return file;
}

// 2. 设置超时
const analysisPromise = ImageAnalysisService.analyzeImage(file);
const timeoutPromise = new Promise((_, reject) =>
  setTimeout(() => reject(new Error('分析超时')), 30000)
);
const result = await Promise.race([analysisPromise, timeoutPromise]);

// 3. 降级处理
try {
  const result = await analyzeImage(file);
} catch (error) {
  console.error('AI分析失败,使用默认分类', error);
  return {
    category: 'unknown',
    confidence: 0,
    description: '自动分类失败,请手动选择'
  };
}

十二、性能优化建议

12.1 数据查询优化

问题:项目列表加载慢

优化方案

// 1. 使用分页
query.limit(20);
query.skip(page * 20);

// 2. 只查询必要字段
query.select('title', 'status', 'currentStage', 'deadline', 'updatedAt');

// 3. 使用索引
// 在Parse Server后台为常用查询字段创建索引
// - status
// - currentStage
// - company
// - assignee
// - createdAt
// - updatedAt

// 4. 缓存查询结果
const cacheKey = `projects_${status}_${page}`;
let projects = cache.get(cacheKey);
if (!projects) {
  projects = await query.find();
  cache.set(cacheKey, projects, 60); // 缓存60秒
}

12.2 文件上传优化

优化方案

// 1. 并发上传(限制并发数)
async function uploadFiles(files) {
  const concurrency = 3;
  const results = [];
  for (let i = 0; i < files.length; i += concurrency) {
    const batch = files.slice(i, i + concurrency);
    const batchResults = await Promise.all(
      batch.map(file => uploadFile(file))
    );
    results.push(...batchResults);
  }
  return results;
}

// 2. 断点续传
async function uploadLargeFile(file) {
  const chunkSize = 1024 * 1024; // 1MB
  const chunks = Math.ceil(file.size / chunkSize);
  for (let i = 0; i < chunks; i++) {
    const start = i * chunkSize;
    const end = Math.min(start + chunkSize, file.size);
    const chunk = file.slice(start, end);
    await uploadChunk(chunk, i, chunks);
  }
}

// 3. 压缩图片
async function compressAndUpload(file) {
  const compressed = await imageCompression(file, {
    maxSizeMB: 2,
    maxWidthOrHeight: 1920,
    useWebWorker: true
  });
  return await uploadFile(compressed);
}

12.3 前端渲染优化

优化方案

// 1. 虚拟滚动(大列表)
<cdk-virtual-scroll-viewport itemSize="80" class="project-list">
  <div *cdkVirtualFor="let project of projects">
    {{ project.title }}
  </div>
</cdk-virtual-scroll-viewport>

// 2. 懒加载图片
<img [src]="placeholder" [lazyLoad]="imageUrl" />

// 3. 使用 OnPush 变更检测
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush
})

// 4. 使用 trackBy
<div *ngFor="let project of projects; trackBy: trackByProjectId">
  {{ project.title }}
</div>

trackByProjectId(index: number, project: Project): string {
  return project.id;
}

十三、安全性考虑

13.1 权限控制

实现方式

// 1. 路由守卫
@Injectable()
export class RoleGuard implements CanActivate {
  canActivate(route: ActivatedRouteSnapshot): boolean {
    const currentUser = Parse.User.current();
    const requiredRole = route.data['role'];
    const userRole = currentUser?.get('roleName');
    return userRole === requiredRole;
  }
}

// 2. 数据权限
async function getProjects(userId: string, role: string) {
  const query = new Parse.Query('Project');

  if (role === '设计师') {
    // 设计师只能查看自己负责的项目
    query.equalTo('assignee', userId);
  } else if (role === '客服' || role === '组长') {
    // 客服和组长可以查看所有项目
    // 不添加额外筛选
  }

  return await query.find();
}

// 3. 操作权限
function canEditProject(project: Project, user: User): boolean {
  const role = user.get('roleName');
  const assigneeId = project.get('assignee')?.id;

  if (role === '管理员' || role === '组长') {
    return true;
  }

  if (role === '客服') {
    const createdBy = project.get('data')?.createdBy;
    return createdBy === user.id;
  }

  if (role === '设计师') {
    return assigneeId === user.id;
  }

  return false;
}

13.2 数据验证

实现方式

// 1. 前端验证
function validateProjectData(data: any): string[] {
  const errors: string[] = [];

  if (!data.title || data.title.trim().length === 0) {
    errors.push('项目名称不能为空');
  }

  if (!data.customerId) {
    errors.push('请选择客户');
  }

  if (data.deadline && new Date(data.deadline) < new Date()) {
    errors.push('截止时间不能早于当前时间');
  }

  return errors;
}

// 2. 后端验证(Parse Cloud Code)
Parse.Cloud.beforeSave('Project', async (request) => {
  const project = request.object;

  // 验证必填字段
  if (!project.get('title')) {
    throw new Parse.Error(400, '项目名称不能为空');
  }

  // 验证数据格式
  const deadline = project.get('deadline');
  if (deadline && !(deadline instanceof Date)) {
    throw new Parse.Error(400, '截止时间格式错误');
  }

  // 验证权限
  const user = request.user;
  if (!user) {
    throw new Parse.Error(401, '未登录');
  }

  const role = user.get('roleName');
  if (!['客服', '组长', '管理员'].includes(role)) {
    throw new Parse.Error(403, '无权限创建项目');
  }
});

13.3 敏感数据保护

实现方式

// 1. 脱敏显示
function maskPhone(phone: string): string {
  if (!phone || phone.length < 11) return phone;
  return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}

function maskIdCard(idCard: string): string {
  if (!idCard || idCard.length < 18) return idCard;
  return idCard.replace(/(\d{6})\d{8}(\d{4})/, '$1********$2');
}

// 2. 加密存储
async function savePaymentInfo(data: any) {
  const encrypted = await encrypt(JSON.stringify(data));
  project.set('paymentInfo', encrypted);
  await project.save();
}

async function getPaymentInfo(project: Project) {
  const encrypted = project.get('paymentInfo');
  const decrypted = await decrypt(encrypted);
  return JSON.parse(decrypted);
}

// 3. 日志记录
async function logSensitiveOperation(
  userId: string,
  action: string,
  entityId: string,
  details: any
) {
  const log = new Parse.Object('AuditLog');
  log.set('user', userId);
  log.set('action', action);
  log.set('entityId', entityId);
  log.set('details', details);
  log.set('timestamp', new Date());
  log.set('ip', request.ip);
  await log.save();
}

十四、未来扩展方向

14.1 功能扩展

1. 智能推荐

  • 根据客户需求推荐设计师
  • 根据项目类型推荐设计方案
  • 根据历史数据推荐报价

2. 数据分析

  • 项目周期分析
  • 设计师绩效分析
  • 客户满意度分析
  • 收入趋势分析

3. 自动化流程

  • 自动分配设计师(基于负载和能力)
  • 自动催办逾期任务
  • 自动生成周报/月报
  • 自动结算设计师费用

4. 移动端支持

  • 响应式设计
  • 移动端专属功能
  • 离线支持
  • 推送通知

14.2 技术升级

1. 性能优化

  • 服务端渲染(SSR)
  • 静态站点生成(SSG)
  • 边缘计算(Edge Computing)
  • CDN加速

2. AI能力增强

  • 更精准的图像识别
  • 自然语言处理(NLP)
  • 智能客服机器人
  • 设计方案生成

3. 数据安全

  • 端到端加密
  • 区块链存证
  • 多因素认证(MFA)
  • 零信任架构

4. 集成能力

  • 第三方设计工具集成
  • 财务系统集成
  • CRM系统集成
  • 项目管理工具集成

附录

A. 数据表完整字段清单

详见第三章"数据字段汇总"

B. API接口文档

详见独立API文档

C. 错误码对照表

错误码 说明 解决方案
400 请求参数错误 检查请求参数格式
401 未登录 重新登录
403 无权限 联系管理员分配权限
404 资源不存在 检查资源ID是否正确
500 服务器错误 联系技术支持

D. 版本更新日志

v1.0.0 (2025-01-15)

  • 初始版本发布
  • 客服板块基础功能
  • 管理员板块基础功能

v1.1.0 (2025-02-01)

  • 新增AI图像分析功能
  • 优化拖拽上传体验
  • 修复已知问题

v1.2.0 (2025-03-01)

  • 新增案例库统计功能
  • 优化项目列表性能
  • 新增员工信息面板

文档版本:v1.0 最后更新:2025-01-15 维护人员:产品团队 联系方式:product@example.com