|
@@ -1,495 +0,0 @@
|
|
|
-import { Injectable } from '@angular/core';
|
|
|
-import { FmodeParse, FmodeObject } from 'fmode-ng/parse';
|
|
|
-
|
|
|
-const Parse = FmodeParse.with('nova');
|
|
|
-
|
|
|
-export interface ProjectSpace {
|
|
|
- id: string;
|
|
|
- name: string;
|
|
|
- type: string;
|
|
|
- area?: number;
|
|
|
- priority: number;
|
|
|
- status: string;
|
|
|
- complexity: string;
|
|
|
- metadata?: any;
|
|
|
- estimatedBudget?: number;
|
|
|
- estimatedDuration?: number;
|
|
|
- order: number;
|
|
|
-}
|
|
|
-
|
|
|
-export interface SpaceProgress {
|
|
|
- spaceId: string;
|
|
|
- stage: string;
|
|
|
- progress: number;
|
|
|
- status: string;
|
|
|
- timeline?: any[];
|
|
|
- blockers?: string[];
|
|
|
- estimatedCompletion?: Date;
|
|
|
- actualCompletion?: Date;
|
|
|
-}
|
|
|
-
|
|
|
-export interface SpaceRequirement {
|
|
|
- spaceId: string;
|
|
|
- spaceName: string;
|
|
|
- spaceType: string;
|
|
|
- colorRequirement: any;
|
|
|
- spaceStructureRequirement: any;
|
|
|
- materialRequirement: any;
|
|
|
- lightingRequirement: any;
|
|
|
- specificRequirements: any;
|
|
|
- referenceImages?: string[];
|
|
|
- referenceFiles?: any[];
|
|
|
-}
|
|
|
-
|
|
|
-export interface CrossSpaceRequirement {
|
|
|
- id: string;
|
|
|
- type: string;
|
|
|
- description: string;
|
|
|
- primarySpaceId: string;
|
|
|
- relatedSpaceIds: string[];
|
|
|
- requirements: any;
|
|
|
-}
|
|
|
-
|
|
|
-@Injectable({
|
|
|
- providedIn: 'root'
|
|
|
-})
|
|
|
-export class MultiSpaceService {
|
|
|
-
|
|
|
- constructor() {}
|
|
|
-
|
|
|
- /**
|
|
|
- * 创建项目空间
|
|
|
- */
|
|
|
- async createSpace(projectId: string, spaceData: Partial<ProjectSpace>): Promise<ProjectSpace> {
|
|
|
- try {
|
|
|
- const ProjectSpace = Parse.Object.extend('ProjectSpace');
|
|
|
- const space = new ProjectSpace();
|
|
|
-
|
|
|
- // 获取项目
|
|
|
- const projectQuery = new Parse.Query('Project');
|
|
|
- const project = await projectQuery.get(projectId);
|
|
|
-
|
|
|
- // 设置空间字段
|
|
|
- space.set('project', project);
|
|
|
- space.set('name', spaceData.name || '');
|
|
|
- space.set('type', spaceData.type || 'other');
|
|
|
- space.set('area', spaceData.area || 0);
|
|
|
- space.set('priority', spaceData.priority || 5);
|
|
|
- space.set('status', spaceData.status || 'not_started');
|
|
|
- space.set('complexity', spaceData.complexity || 'medium');
|
|
|
- space.set('metadata', spaceData.metadata || {});
|
|
|
- space.set('estimatedBudget', spaceData.estimatedBudget || 0);
|
|
|
- space.set('estimatedDuration', spaceData.estimatedDuration || 0);
|
|
|
- space.set('order', spaceData.order || 0);
|
|
|
-
|
|
|
- const savedSpace = await space.save();
|
|
|
- return this.parseSpaceData(savedSpace);
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('创建空间失败:', error);
|
|
|
- throw error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取项目空间列表
|
|
|
- */
|
|
|
- async getProjectSpaces(projectId: string): Promise<ProjectSpace[]> {
|
|
|
- try {
|
|
|
- const query = new Parse.Query('ProjectSpace');
|
|
|
- query.equalTo('project', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'Project',
|
|
|
- objectId: projectId
|
|
|
- });
|
|
|
- query.ascending('order');
|
|
|
- query.equalTo('isDeleted', false);
|
|
|
-
|
|
|
- const results = await query.find();
|
|
|
- return results.map(space => this.parseSpaceData(space));
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('获取项目空间失败:', error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新空间信息
|
|
|
- */
|
|
|
- async updateSpace(spaceId: string, updateData: Partial<ProjectSpace>): Promise<ProjectSpace> {
|
|
|
- try {
|
|
|
- const query = new Parse.Query('ProjectSpace');
|
|
|
- const space = await query.get(spaceId);
|
|
|
-
|
|
|
- // 更新字段
|
|
|
- if (updateData.name !== undefined) space.set('name', updateData.name);
|
|
|
- if (updateData.type !== undefined) space.set('type', updateData.type);
|
|
|
- if (updateData.area !== undefined) space.set('area', updateData.area);
|
|
|
- if (updateData.priority !== undefined) space.set('priority', updateData.priority);
|
|
|
- if (updateData.status !== undefined) space.set('status', updateData.status);
|
|
|
- if (updateData.complexity !== undefined) space.set('complexity', updateData.complexity);
|
|
|
- if (updateData.metadata !== undefined) space.set('metadata', updateData.metadata);
|
|
|
- if (updateData.estimatedBudget !== undefined) space.set('estimatedBudget', updateData.estimatedBudget);
|
|
|
- if (updateData.estimatedDuration !== undefined) space.set('estimatedDuration', updateData.estimatedDuration);
|
|
|
- if (updateData.order !== undefined) space.set('order', updateData.order);
|
|
|
-
|
|
|
- const savedSpace = await space.save();
|
|
|
- return this.parseSpaceData(savedSpace);
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('更新空间失败:', error);
|
|
|
- throw error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除空间
|
|
|
- */
|
|
|
- async deleteSpace(spaceId: string): Promise<void> {
|
|
|
- try {
|
|
|
- const query = new Parse.Query('ProjectSpace');
|
|
|
- const space = await query.get(spaceId);
|
|
|
- space.set('isDeleted', true);
|
|
|
- await space.save();
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('删除空间失败:', error);
|
|
|
- throw error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新空间进度
|
|
|
- */
|
|
|
- async updateSpaceProgress(progressData: SpaceProgress): Promise<void> {
|
|
|
- try {
|
|
|
- // 查找现有进度记录
|
|
|
- const query = new Parse.Query('SpaceProgress');
|
|
|
- query.equalTo('spaceId', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'ProjectSpace',
|
|
|
- objectId: progressData.spaceId
|
|
|
- });
|
|
|
- query.equalTo('stage', progressData.stage);
|
|
|
-
|
|
|
- let progressRecord = await query.first();
|
|
|
-
|
|
|
- if (!progressRecord) {
|
|
|
- // 创建新记录
|
|
|
- const SpaceProgress = Parse.Object.extend('SpaceProgress');
|
|
|
- progressRecord = new SpaceProgress();
|
|
|
- progressRecord.set('spaceId', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'ProjectSpace',
|
|
|
- objectId: progressData.spaceId
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 更新进度数据
|
|
|
- progressRecord.set('stage', progressData.stage);
|
|
|
- progressRecord.set('progress', progressData.progress);
|
|
|
- progressRecord.set('status', progressData.status);
|
|
|
- progressRecord.set('timeline', progressData.timeline || []);
|
|
|
- progressRecord.set('blockers', progressData.blockers || []);
|
|
|
- progressRecord.set('estimatedCompletion', progressData.estimatedCompletion);
|
|
|
- progressRecord.set('actualCompletion', progressData.actualCompletion);
|
|
|
-
|
|
|
- await progressRecord.save();
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('更新空间进度失败:', error);
|
|
|
- throw error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取空间进度
|
|
|
- */
|
|
|
- async getSpaceProgress(spaceId: string, stage?: string): Promise<SpaceProgress[]> {
|
|
|
- try {
|
|
|
- const query = new Parse.Query('SpaceProgress');
|
|
|
- query.equalTo('spaceId', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'ProjectSpace',
|
|
|
- objectId: spaceId
|
|
|
- });
|
|
|
-
|
|
|
- if (stage) {
|
|
|
- query.equalTo('stage', stage);
|
|
|
- }
|
|
|
-
|
|
|
- const results = await query.find();
|
|
|
- return results.map(record => ({
|
|
|
- spaceId: record.get('spaceId')?.objectId,
|
|
|
- stage: record.get('stage'),
|
|
|
- progress: record.get('progress'),
|
|
|
- status: record.get('status'),
|
|
|
- timeline: record.get('timeline'),
|
|
|
- blockers: record.get('blockers'),
|
|
|
- estimatedCompletion: record.get('estimatedCompletion'),
|
|
|
- actualCompletion: record.get('actualCompletion')
|
|
|
- }));
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('获取空间进度失败:', error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 创建空间依赖关系
|
|
|
- */
|
|
|
- async createSpaceDependency(
|
|
|
- projectId: string,
|
|
|
- fromSpaceId: string,
|
|
|
- toSpaceId: string,
|
|
|
- dependencyType: string,
|
|
|
- description: string
|
|
|
- ): Promise<void> {
|
|
|
- try {
|
|
|
- const SpaceDependency = Parse.Object.extend('SpaceDependency');
|
|
|
- const dependency = new SpaceDependency();
|
|
|
-
|
|
|
- // 获取项目
|
|
|
- const projectQuery = new Parse.Query('Project');
|
|
|
- const project = await projectQuery.get(projectId);
|
|
|
-
|
|
|
- dependency.set('project', project);
|
|
|
- dependency.set('fromSpace', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'ProjectSpace',
|
|
|
- objectId: fromSpaceId
|
|
|
- });
|
|
|
- dependency.set('toSpace', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'ProjectSpace',
|
|
|
- objectId: toSpaceId
|
|
|
- });
|
|
|
- dependency.set('type', dependencyType);
|
|
|
- dependency.set('description', description);
|
|
|
- dependency.set('status', 'pending');
|
|
|
- dependency.set('confidence', 0.8);
|
|
|
-
|
|
|
- await dependency.save();
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('创建空间依赖失败:', error);
|
|
|
- throw error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取空间依赖关系
|
|
|
- */
|
|
|
- async getSpaceDependencies(projectId: string): Promise<any[]> {
|
|
|
- try {
|
|
|
- const query = new Parse.Query('SpaceDependency');
|
|
|
- query.equalTo('project', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'Project',
|
|
|
- objectId: projectId
|
|
|
- });
|
|
|
- query.include('fromSpace', 'toSpace');
|
|
|
-
|
|
|
- const results = await query.find();
|
|
|
- return results.map(record => ({
|
|
|
- id: record.id,
|
|
|
- fromSpace: record.get('fromSpace'),
|
|
|
- toSpace: record.get('toSpace'),
|
|
|
- type: record.get('type'),
|
|
|
- description: record.get('description'),
|
|
|
- status: record.get('status'),
|
|
|
- confidence: record.get('confidence')
|
|
|
- }));
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('获取空间依赖失败:', error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 保存空间需求
|
|
|
- */
|
|
|
- async saveSpaceRequirements(
|
|
|
- projectId: string,
|
|
|
- spaceId: string,
|
|
|
- requirements: SpaceRequirement
|
|
|
- ): Promise<void> {
|
|
|
- try {
|
|
|
- // 查找多空间需求记录
|
|
|
- const query = new Parse.Query('MultiSpaceRequirement');
|
|
|
- query.equalTo('project', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'Project',
|
|
|
- objectId: projectId
|
|
|
- });
|
|
|
-
|
|
|
- let multiSpaceReq = await query.first();
|
|
|
-
|
|
|
- if (!multiSpaceReq) {
|
|
|
- // 创建多空间需求记录
|
|
|
- const MultiSpaceRequirement = Parse.Object.extend('MultiSpaceRequirement');
|
|
|
- multiSpaceReq = new MultiSpaceRequirement();
|
|
|
- multiSpaceReq.set('project', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'Project',
|
|
|
- objectId: projectId
|
|
|
- });
|
|
|
- multiSpaceReq.set('requirementId', `req_${Date.now()}`);
|
|
|
- multiSpaceReq.set('globalRequirements', {});
|
|
|
- multiSpaceReq.set('spaceRequirements', []);
|
|
|
- multiSpaceReq.set('crossSpaceRequirements', []);
|
|
|
- multiSpaceReq.set('status', 'draft');
|
|
|
- multiSpaceReq.set('completenessCheck', {});
|
|
|
- multiSpaceReq.set('createdAt', new Date());
|
|
|
- multiSpaceReq.set('updatedAt', new Date());
|
|
|
-
|
|
|
- await multiSpaceReq.save();
|
|
|
- }
|
|
|
-
|
|
|
- // 创建空间需求记录
|
|
|
- const SpaceRequirement = Parse.Object.extend('SpaceRequirement');
|
|
|
- const spaceRequirement = new SpaceRequirement();
|
|
|
-
|
|
|
- spaceRequirement.set('multiSpaceReqId', multiSpaceReq);
|
|
|
- spaceRequirement.set('spaceId', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'ProjectSpace',
|
|
|
- objectId: spaceId
|
|
|
- });
|
|
|
- spaceRequirement.set('spaceName', requirements.spaceName);
|
|
|
- spaceRequirement.set('spaceType', requirements.spaceType);
|
|
|
- spaceRequirement.set('colorRequirement', requirements.colorRequirement);
|
|
|
- spaceRequirement.set('spaceStructureRequirement', requirements.spaceStructureRequirement);
|
|
|
- spaceRequirement.set('materialRequirement', requirements.materialRequirement);
|
|
|
- spaceRequirement.set('lightingRequirement', requirements.lightingRequirement);
|
|
|
- spaceRequirement.set('specificRequirements', requirements.specificRequirements);
|
|
|
-
|
|
|
- await spaceRequirement.save();
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('保存空间需求失败:', error);
|
|
|
- throw error;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取空间需求
|
|
|
- */
|
|
|
- async getSpaceRequirements(projectId: string, spaceId?: string): Promise<SpaceRequirement[]> {
|
|
|
- try {
|
|
|
- // 获取多空间需求记录
|
|
|
- const multiSpaceQuery = new Parse.Query('MultiSpaceRequirement');
|
|
|
- multiSpaceQuery.equalTo('project', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'Project',
|
|
|
- objectId: projectId
|
|
|
- });
|
|
|
-
|
|
|
- const multiSpaceReq = await multiSpaceQuery.first();
|
|
|
- if (!multiSpaceReq) return [];
|
|
|
-
|
|
|
- // 获取空间需求记录
|
|
|
- const query = new Parse.Query('SpaceRequirement');
|
|
|
- query.equalTo('multiSpaceReqId', multiSpaceReq);
|
|
|
-
|
|
|
- if (spaceId) {
|
|
|
- query.equalTo('spaceId', {
|
|
|
- __type: 'Pointer',
|
|
|
- className: 'ProjectSpace',
|
|
|
- objectId: spaceId
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- const results = await query.find();
|
|
|
- return results.map(record => ({
|
|
|
- spaceId: record.get('spaceId')?.objectId,
|
|
|
- spaceName: record.get('spaceName'),
|
|
|
- spaceType: record.get('spaceType'),
|
|
|
- colorRequirement: record.get('colorRequirement'),
|
|
|
- spaceStructureRequirement: record.get('spaceStructureRequirement'),
|
|
|
- materialRequirement: record.get('materialRequirement'),
|
|
|
- lightingRequirement: record.get('lightingRequirement'),
|
|
|
- specificRequirements: record.get('specificRequirements'),
|
|
|
- referenceImages: record.get('referenceImages') || [],
|
|
|
- referenceFiles: record.get('referenceFiles') || []
|
|
|
- }));
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('获取空间需求失败:', error);
|
|
|
- return [];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算空间完成进度
|
|
|
- */
|
|
|
- calculateSpaceProgress(spaceId: string, allStages: string[]): number {
|
|
|
- // 这里需要从缓存或数据库中获取各阶段进度
|
|
|
- // 暂时返回模拟数据
|
|
|
- return Math.floor(Math.random() * 100);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取空间类型图标
|
|
|
- */
|
|
|
- getSpaceIcon(spaceType: string): string {
|
|
|
- const iconMap: Record<string, string> = {
|
|
|
- 'living_room': 'living-room',
|
|
|
- 'bedroom': 'bedroom',
|
|
|
- 'kitchen': 'kitchen',
|
|
|
- 'bathroom': 'bathroom',
|
|
|
- 'dining_room': 'dining-room',
|
|
|
- 'study': 'study',
|
|
|
- 'balcony': 'balcony',
|
|
|
- 'corridor': 'corridor',
|
|
|
- 'storage': 'storage',
|
|
|
- 'entrance': 'entrance',
|
|
|
- 'other': 'room'
|
|
|
- };
|
|
|
-
|
|
|
- return iconMap[spaceType] || 'room';
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取空间类型名称
|
|
|
- */
|
|
|
- getSpaceTypeName(spaceType: string): string {
|
|
|
- const nameMap: Record<string, string> = {
|
|
|
- 'living_room': '客厅',
|
|
|
- 'bedroom': '卧室',
|
|
|
- 'kitchen': '厨房',
|
|
|
- 'bathroom': '卫生间',
|
|
|
- 'dining_room': '餐厅',
|
|
|
- 'study': '书房',
|
|
|
- 'balcony': '阳台',
|
|
|
- 'corridor': '走廊',
|
|
|
- 'storage': '储物间',
|
|
|
- 'entrance': '玄关',
|
|
|
- 'other': '其他'
|
|
|
- };
|
|
|
-
|
|
|
- return nameMap[spaceType] || '其他';
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 解析空间数据
|
|
|
- */
|
|
|
- private parseSpaceData(space: any): ProjectSpace {
|
|
|
- return {
|
|
|
- id: space.id,
|
|
|
- name: space.get('name'),
|
|
|
- type: space.get('type'),
|
|
|
- area: space.get('area'),
|
|
|
- priority: space.get('priority'),
|
|
|
- status: space.get('status'),
|
|
|
- complexity: space.get('complexity'),
|
|
|
- metadata: space.get('metadata'),
|
|
|
- estimatedBudget: space.get('estimatedBudget'),
|
|
|
- estimatedDuration: space.get('estimatedDuration'),
|
|
|
- order: space.get('order')
|
|
|
- };
|
|
|
- }
|
|
|
-}
|