日期: 2025-10-24
问题:
现象:
在 http://localhost:4200/admin/project-detail/APwk78jnrh/order 分配设计师时,"指派空间场景"没有选项。
原因:
team-assign.component.ts 通过 ProductSpaceService.getProjectProductSpaces() 获取项目空间:
// team-assign.component.ts 第94-107行
async loadProjectSpaces(): Promise<void> {
  if (!this.project) return;
  
  try {
    this.loadingSpaces = true;
    const projectId = this.project.id || '';
    // 从Product表查询该项目的空间
    this.projectSpaces = await this.productSpaceService.getProjectProductSpaces(projectId);
  } catch (err) {
    console.error('加载项目空间失败:', err);
  } finally {
    this.loadingSpaces = false;
    this.cdr.markForCheck();
  }
}
ProductSpaceService.getProjectProductSpaces() 从 Product 表查询:
// product-space.service.ts 第125-143行
async getProjectProductSpaces(projectId: string): Promise<Project[]> {
  try {
    const query = new Parse.Query('Product');
    query.equalTo('project', {
      __type: 'Pointer',
      className: 'Project',
      objectId: projectId
    });
    query.include('profile');
    query.ascending('createdAt');
    const results = await query.find();
    return results.map(product => this.parseProductData(product));
  } catch (error) {
    console.error('获取项目产品空间失败:', error);
    return [];
  }
}
根本原因: 项目ID为 APwk78jnrh 的项目在 Product 表中没有任何记录。
现象:
项目列表中"负责人"列显示"未分配",应该显示组长名字。
数据流:
Parse数据库 Project表
  ↓
  assignee字段 (Pointer<Profile>) = null
  ↓
project-management.ts 第107行
  assignee: json.assigneeName || '未分配'
  ↓
前端显示 "未分配"
根本原因: 项目创建时,assignee 字段没有被设置。按业务逻辑,项目的负责人应该是项目组的组长(department.leader)。
方案A: 在"订单分配"阶段创建空间(推荐)
在 stage-order.component.ts 的订单分配阶段,用户填写空间信息后自动创建 Product 记录。
位置: src/modules/project/pages/project-detail/stages/stage-order.component.ts
逻辑:
async saveSpaces() {
  // 遍历用户添加的空间
  for (const space of this.spaces) {
    // 调用 ProductSpaceService.createProductSpace() 创建Product记录
    await this.productSpaceService.createProductSpace(this.project.id, {
      name: space.name,
      type: space.type,
      area: space.area,
      priority: space.priority,
      complexity: space.complexity,
      estimatedBudget: space.budget
    });
  }
}
方案B: 在分配设计师时动态创建空间
如果没有空间,显示提示:"请先在订单分配阶段添加空间"。
方案C: 提供手动添加空间的入口
在分配设计师弹窗中添加"添加空间"按钮。
关键修改: 在选择项目组(Department)时,自动将组长(department.leader)设置为项目的 assignee。
位置: src/modules/project/components/team-assign/team-assign.component.ts 第128-134行
修改 selectDepartment 方法:
async selectDepartment(department: FmodeObject) {
  this.selectedDepartment = department;
  this.selectedDesigner = null;
  this.departmentMembers = [];
  // ✅ 新增:自动设置组长为项目负责人
  const leader = department.get('leader');
  if (leader && this.project) {
    try {
      // 更新项目的assignee字段为组长
      this.project.set('assignee', leader);
      this.project.set('department', department);
      await this.project.save();
      console.log('✅ 项目负责人已设置为组长:', leader.get('name'));
    } catch (error) {
      console.error('❌ 设置项目负责人失败:', error);
    }
  }
  await this.loadDepartmentMembers(department);
}
说明:
department.leader)assignee 字段department 字段位置: src/app/pages/admin/services/project.service.ts 第65-110行
在 createProject 方法中添加逻辑:
async createProject(data: {
  title: string;
  customerId?: string;
  assigneeId?: string; // 可以是组长ID
  departmentId?: string; // 新增:项目组ID
  status?: string;
  currentStage?: string;
  deadline?: Date;
  data?: any;
}): Promise<FmodeObject> {
  const projectData: any = {
    title: data.title,
    status: data.status || '待分配',
    currentStage: data.currentStage || '订单分配'
  };
  // 设置客户指针
  if (data.customerId) {
    projectData.customer = {
      __type: 'Pointer',
      className: 'ContactInfo',
      objectId: data.customerId
    };
  }
  // ✅ 新增:如果提供了项目组,获取组长作为默认负责人
  if (data.departmentId) {
    const departmentQuery = new Parse.Query('Department');
    departmentQuery.include('leader');
    const department = await departmentQuery.get(data.departmentId);
    
    if (department) {
      projectData.department = department.toPointer();
      
      // 获取组长
      const leader = department.get('leader');
      if (leader && !data.assigneeId) {
        projectData.assignee = leader.toPointer();
        console.log('✅ 项目负责人默认为组长:', leader.get('name'));
      }
    }
  }
  // 设置负责人指针(如果明确指定)
  if (data.assigneeId) {
    projectData.assignee = {
      __type: 'Pointer',
      className: 'Profile',
      objectId: data.assigneeId
    };
  }
  if (data.deadline) {
    projectData.deadline = data.deadline;
  }
  if (data.data) {
    projectData.data = data.data;
  }
  const project = this.adminData.createObject('Project', projectData);
  return await this.adminData.save(project);
}
| 字段 | 类型 | 说明 | 新增/修改 | 
|---|---|---|---|
| department | Pointer | 项目组 | ✅ 确保填充 | 
| assignee | Pointer | 项目负责人(组长) | ✅ 自动设置为组长 | 
| title | String | 项目名称 | 已有 | 
| customer | Pointer | 客户 | 已有 | 
| status | String | 项目状态 | 已有 | 
| currentStage | String | 当前阶段 | 已有 | 
| 字段 | 类型 | 说明 | 
|---|---|---|
| project | Pointer | 所属项目 | 
| productName | String | 空间名称(如"客厅") | 
| productType | String | 空间类型(如"living_room") | 
| space | Object | 空间详细信息 | 
| space.area | Number | 面积 | 
| space.priority | Number | 优先级 | 
| space.complexity | String | 复杂度 | 
| quotation | Object | 报价信息 | 
| requirements | Object | 需求信息 | 
| profile | Pointer | 负责该空间的设计师 | 
| 字段 | 类型 | 说明 | 
|---|---|---|
| name | String | 项目组名称 | 
| leader | Pointer | 组长 | 
| type | String | 'project' (项目组) | 
| company | String | 公司ID | 
| 字段 | 类型 | 说明 | 
|---|---|---|
| name | String | 姓名 | 
| roleName | String | '组长' 或 '组员' | 
| department | String | 部门ID | 
| company | String | 公司ID | 
进入订单分配阶段
http://localhost:4200/admin/project-detail/APwk78jnrh/order
添加空间
分配设计师
创建新项目时指定项目组
POST /Project
{
 "title": "测试项目",
 "departmentId": "xxx", // 项目组ID
 "status": "待分配"
}
验证数据库
// Parse Dashboard 查看 Project 表
- assignee字段应该指向组长的Profile
- department字段应该指向该项目组
在项目详情页选择项目组
验证项目列表
http://localhost:4200/admin/project-management
项目创建时:
departmentId,自动获取组长作为 assigneeassigneeId,使用指定的人员选择项目组时:
team-assign 组件中选择项目组assigneedepartment 字段项目列表显示:
assignee.name 获取负责人名字订单分配阶段 (stage-order):
ProductSpaceService.createProductSpace() 创建 Product 记录分配设计师时 (team-assign):
Product 表查询该项目的所有空间ProjectTeam.data.spaces 中✅ src/modules/project/components/team-assign/team-assign.component.ts
selectDepartment 方法✅ src/app/pages/admin/services/project.service.ts
createProject 方法⚠️ src/modules/project/pages/project-detail/stages/stage-order.component.ts
项目列表:
项目名称                             | 客户      | 负责人    | 状态
张家界凤凰城三期项目 紫空居..        | 未知客户  | 未分配    | 待分配
分配设计师:
指派空间场景
(空)
项目列表:
项目名称                             | 客户      | 负责人    | 状态
张家界凤凰城三期项目 紫空居..        | 张先生    | 汪奥      | 进行中
分配设计师:
指派空间场景 *
☑ 客厅
☐ 主卧
☐ 次卧
☐ 厨房
修改完成后,项目负责人将自动设置为组长,且分配设计师时能看到项目的所有空间! ✨