| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- import { Injectable } from '@angular/core';
- import { FmodeParse } from 'fmode-ng/parse';
- const Parse = FmodeParse.with('nova');
- export interface Project {
- id: string;
- name: string; // productName
- type: string; // productType
- area?: number; // space.area
- priority: number; // space.priority
- status: string; // Product.status
- complexity: string; // space.complexity
- metadata?: any; // space metadata
- estimatedBudget?: number; // quotation.price
- estimatedDuration?: number; // space metadata
- order: number;
- projectId: string;
- designerId?: string; // profile pointer
- quotation?: any; // Product.quotation
- requirements?: any; // Product.requirements
- reviews?: any; // Product.reviews
- }
- export interface ProductProgress {
- productId: string;
- stage: string;
- progress: number;
- status: string;
- timeline?: any[];
- blockers?: string[];
- estimatedCompletion?: Date;
- actualCompletion?: Date;
- }
- export interface ProductRequirement {
- productId: string;
- productName: string;
- productType: string;
- colorRequirement: any;
- spaceStructureRequirement: any;
- materialRequirement: any;
- lightingRequirement: any;
- specificRequirements: any;
- referenceImages?: string[];
- referenceFiles?: any[];
- }
- @Injectable({
- providedIn: 'root'
- })
- export class ProductSpaceService {
- constructor() {}
- /**
- * 创建产品空间(即创建Product)
- */
- async createProductSpace(projectId: string, spaceData: Partial<Project>): Promise<Project> {
- try {
- const Product = Parse.Object.extend('Product');
- const product = new Product();
- // 获取项目
- const projectQuery = new Parse.Query('Project');
- const project = await projectQuery.get(projectId);
- // 设置产品字段
- product.set('project', project);
- product.set('productName', spaceData.name || '');
- product.set('productType', spaceData.type || 'other');
- product.set('status', spaceData.status || 'not_started');
- // 设置空间信息
- product.set('space', {
- spaceName: spaceData.name || '',
- area: spaceData.area || 0,
- dimensions: { length: 0, width: 0, height: 0 },
- features: [],
- constraints: [],
- priority: spaceData.priority || 5,
- complexity: spaceData.complexity || 'medium'
- });
- // 设置报价信息
- if (spaceData.estimatedBudget) {
- product.set('quotation', {
- price: spaceData.estimatedBudget,
- currency: 'CNY',
- breakdown: {},
- status: 'draft',
- validUntil: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
- });
- }
- // 设置需求信息
- product.set('requirements', {
- colorRequirement: spaceData.requirements?.colorRequirement || {},
- spaceStructureRequirement: spaceData.requirements?.spaceStructureRequirement || {},
- materialRequirement: spaceData.requirements?.materialRequirement || {},
- lightingRequirement: spaceData.requirements?.lightingRequirement || {},
- specificRequirements: spaceData.requirements?.specificRequirements || [],
- constraints: {}
- });
- // 设置设计师
- if (spaceData.designerId) {
- const designerQuery = new Parse.Query('Profile');
- const designer = await designerQuery.get(spaceData.designerId);
- product.set('profile', designer);
- }
- const savedProduct = await product.save();
- return this.parseProductData(savedProduct);
- } catch (error) {
- console.error('创建产品空间失败:', error);
- throw error;
- }
- }
- /**
- * 获取项目产品空间列表
- */
- 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();
- const mapped = results.map(product => this.parseProductData(product));
- // 去重:按名称(忽略大小写与首尾空格)保留第一个
- const seen = new Set<string>();
- const unique: Project[] = [];
- for (const p of mapped) {
- const key = (p.name || '').trim().toLowerCase();
- if (!seen.has(key)) {
- seen.add(key);
- unique.push(p);
- }
- }
- return unique;
- } catch (error) {
- console.error('获取项目产品空间失败:', error);
- return [];
- }
- }
- /**
- * 更新产品空间信息
- */
- async updateProductSpace(productId: string, updateData: Partial<Project>): Promise<Project> {
- try {
- const query = new Parse.Query('Product');
- const product = await query.get(productId);
- // 更新产品基本信息
- if (updateData.name !== undefined) product.set('productName', updateData.name);
- if (updateData.type !== undefined) product.set('productType', updateData.type);
- if (updateData.status !== undefined) product.set('status', updateData.status);
- // 更新空间信息
- if (updateData.area !== undefined || updateData.priority !== undefined || updateData.complexity !== undefined) {
- const space = product.get('space') || {};
- if (updateData.area !== undefined) space.area = updateData.area;
- if (updateData.priority !== undefined) space.priority = updateData.priority;
- if (updateData.complexity !== undefined) space.complexity = updateData.complexity;
- product.set('space', space);
- }
- // 更新报价信息
- if (updateData.estimatedBudget !== undefined) {
- const quotation = product.get('quotation') || {};
- quotation.price = updateData.estimatedBudget;
- product.set('quotation', quotation);
- }
- // 更新需求信息
- if (updateData.requirements !== undefined) {
- const requirements = product.get('requirements') || {};
- Object.assign(requirements, updateData.requirements);
- product.set('requirements', requirements);
- }
- // 更新设计师
- if (updateData.designerId !== undefined) {
- if (updateData.designerId) {
- const designerQuery = new Parse.Query('Profile');
- const designer = await designerQuery.get(updateData.designerId);
- product.set('profile', designer);
- } else {
- product.unset('profile');
- }
- }
- const savedProduct = await product.save();
- return this.parseProductData(savedProduct);
- } catch (error) {
- console.error('更新产品空间失败:', error);
- throw error;
- }
- }
- /**
- * 删除产品空间
- */
- async deleteProductSpace(productId: string): Promise<void> {
- try {
- const query = new Parse.Query('Product');
- const product = await query.get(productId);
- await product.destroy();
- } catch (error) {
- console.error('删除产品空间失败:', error);
- throw error;
- }
- }
- /**
- * 更新产品进度
- */
- async updateProductProgress(progressData: ProductProgress): Promise<void> {
- try {
- // 在Product的data字段中存储进度信息
- const query = new Parse.Query('Product');
- const product = await query.get(progressData.productId);
- const data = product.get('data') || {};
- if (!data.progress) data.progress = [];
- // 查找现有进度记录
- let progressRecord = data.progress.find((p: any) => p.stage === progressData.stage);
- if (!progressRecord) {
- // 创建新进度记录
- progressRecord = {
- stage: progressData.stage,
- progress: 0,
- status: 'not_started',
- timeline: [],
- blockers: []
- };
- data.progress.push(progressRecord);
- }
- // 更新进度数据
- progressRecord.progress = progressData.progress;
- progressRecord.status = progressData.status;
- progressRecord.timeline = progressData.timeline || [];
- progressRecord.blockers = progressData.blockers || [];
- progressRecord.estimatedCompletion = progressData.estimatedCompletion;
- progressRecord.actualCompletion = progressData.actualCompletion;
- product.set('data', data);
- await product.save();
- } catch (error) {
- console.error('更新产品进度失败:', error);
- throw error;
- }
- }
- /**
- * 获取产品进度
- */
- async getProductProgress(productId: string, stage?: string): Promise<ProductProgress[]> {
- try {
- const query = new Parse.Query('Product');
- const product = await query.get(productId);
- const data = product.get('data') || {};
- const progressData = data.progress || [];
- let result = progressData;
- if (stage) {
- result = progressData.filter((p: any) => p.stage === stage);
- }
- return result.map((p: any) => ({
- productId: productId,
- stage: p.stage,
- progress: p.progress,
- status: p.status,
- timeline: p.timeline,
- blockers: p.blockers,
- estimatedCompletion: p.estimatedCompletion,
- actualCompletion: p.actualCompletion
- }));
- } catch (error) {
- console.error('获取产品进度失败:', error);
- return [];
- }
- }
- /**
- * 创建产品依赖关系
- */
- async createProductDependency(
- projectId: string,
- fromProductId: string,
- toProductId: string,
- dependencyType: string,
- description: string
- ): Promise<void> {
- try {
- // 在项目的data字段中存储产品依赖关系
- const projectQuery = new Parse.Query('Project');
- const project = await projectQuery.get(projectId);
- const data = project.get('data') || {};
- if (!data.productDependencies) data.productDependencies = [];
- const dependency = {
- id: `dep_${Date.now()}`,
- fromProductId: fromProductId,
- toProductId: toProductId,
- type: dependencyType,
- description: description,
- status: 'pending',
- confidence: 0.8,
- createdAt: new Date()
- };
- data.productDependencies.push(dependency);
- project.set('data', data);
- await project.save();
- } catch (error) {
- console.error('创建产品依赖失败:', error);
- throw error;
- }
- }
- /**
- * 获取产品依赖关系
- */
- async getProductDependencies(projectId: string): Promise<any[]> {
- try {
- const projectQuery = new Parse.Query('Project');
- const project = await projectQuery.get(projectId);
- const data = project.get('data') || {};
- return data.productDependencies || [];
- } catch (error) {
- console.error('获取产品依赖失败:', error);
- return [];
- }
- }
- /**
- * 保存产品需求
- */
- async saveProductRequirements(
- _projectId: string,
- productId: string,
- requirements: ProductRequirement
- ): Promise<void> {
- try {
- const query = new Parse.Query('Product');
- const product = await query.get(productId);
- // 更新产品的需求信息
- product.set('requirements', {
- colorRequirement: requirements.colorRequirement,
- spaceStructureRequirement: requirements.spaceStructureRequirement,
- materialRequirement: requirements.materialRequirement,
- lightingRequirement: requirements.lightingRequirement,
- specificRequirements: requirements.specificRequirements,
- constraints: {}
- });
- await product.save();
- } catch (error) {
- console.error('保存产品需求失败:', error);
- throw error;
- }
- }
- /**
- * 获取产品需求
- */
- async getProductRequirements(projectId: string, productId?: string): Promise<ProductRequirement[]> {
- try {
- let query = new Parse.Query('Product');
- query.equalTo('project', {
- __type: 'Pointer',
- className: 'Project',
- objectId: projectId
- });
- if (productId) {
- query.equalTo('objectId', productId);
- }
- const results = await query.find();
- return results.map(product => ({
- productId: product.id || '',
- productName: product.get('productName'),
- productType: product.get('productType'),
- colorRequirement: product.get('requirements')?.colorRequirement || {},
- spaceStructureRequirement: product.get('requirements')?.spaceStructureRequirement || {},
- materialRequirement: product.get('requirements')?.materialRequirement || {},
- lightingRequirement: product.get('requirements')?.lightingRequirement || {},
- specificRequirements: product.get('requirements')?.specificRequirements || [],
- referenceImages: product.get('requirements')?.referenceImages || [],
- referenceFiles: product.get('requirements')?.referenceFiles || []
- }));
- } catch (error) {
- console.error('获取产品需求失败:', error);
- return [];
- }
- }
- /**
- * 计算产品完成进度
- */
- calculateProductProgress(_productId: string, _allStages: string[]): number {
- // 这里需要从缓存或数据库中获取各阶段进度
- // 暂时返回模拟数据
- return Math.floor(Math.random() * 100);
- }
- /**
- * 获取产品类型图标
- */
- getProductIcon(productType: 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[productType] || 'room';
- }
- /**
- * 获取产品类型名称
- */
- getProductTypeName(productType: string): string {
- const nameMap: Record<string, string> = {
- 'living_room': '客厅',
- 'bedroom': '卧室',
- 'kitchen': '厨房',
- 'bathroom': '卫生间',
- 'dining_room': '餐厅',
- 'study': '书房',
- 'balcony': '阳台',
- 'corridor': '走廊',
- 'storage': '储物间',
- 'entrance': '玄关',
- 'other': '其他'
- };
- return nameMap[productType] || '其他';
- }
- /**
- * 解析产品数据
- */
- private parseProductData(product: any): Project {
- const space = product.get('space') || {};
- const quotation = product.get('quotation') || {};
- const profile = product.get('profile');
- return {
- id: product.id,
- name: product.get('productName'),
- type: product.get('productType'),
- area: space.area,
- priority: space.priority || 5,
- status: product.get('status'),
- complexity: space.complexity || 'medium',
- metadata: space.metadata || {},
- estimatedBudget: quotation.price,
- estimatedDuration: space.estimatedDuration,
- order: 0, // 使用创建时间排序
- projectId: product.get('project')?.objectId,
- designerId: profile?.id,
- quotation: quotation,
- requirements: product.get('requirements'),
- reviews: product.get('reviews')
- };
- }
- /**
- * 统一空间数据管理 - 核心方法
- * 将所有空间数据统一存储到Project.data.unifiedSpaces中
- */
- async saveUnifiedSpaceData(projectId: string, spaces: any[]): Promise<void> {
- try {
- console.log(`🔄 [统一空间管理] 开始保存统一空间数据,项目ID: ${projectId}, 空间数: ${spaces.length}`);
-
- const projectQuery = new Parse.Query('Project');
- const project = await projectQuery.get(projectId);
-
- const data = project.get('data') || {};
-
- // 统一空间数据结构
- data.unifiedSpaces = spaces.map((space, index) => ({
- id: space.id || `space_${Date.now()}_${index}`,
- name: space.name || `空间${index + 1}`,
- type: space.type || 'other',
- area: space.area || 0,
- priority: space.priority || 5,
- status: space.status || 'not_started',
- complexity: space.complexity || 'medium',
- estimatedBudget: space.estimatedBudget || 0,
- order: space.order !== undefined ? space.order : index,
- // 报价信息
- quotation: {
- price: space.estimatedBudget || 0,
- processes: space.processes || {},
- subtotal: space.subtotal || 0
- },
- // 需求信息
- requirements: space.requirements || {},
- // 设计师分配
- designerId: space.designerId || null,
- // 进度信息
- progress: space.progress || [],
- // 创建和更新时间
- createdAt: space.createdAt || new Date().toISOString(),
- updatedAt: new Date().toISOString()
- }));
-
- // 同时保存到quotation.spaces以保持向后兼容
- if (!data.quotation) data.quotation = {};
- data.quotation.spaces = data.unifiedSpaces.map(space => ({
- name: space.name,
- spaceId: space.id,
- processes: space.quotation.processes,
- subtotal: space.quotation.subtotal
- }));
-
- project.set('data', data);
- await project.save();
-
- // 同步到Product表
- await this.syncUnifiedSpacesToProducts(projectId, data.unifiedSpaces);
-
- console.log(`✅ [统一空间管理] 统一空间数据保存完成`);
- } catch (error) {
- console.error('❌ [统一空间管理] 保存统一空间数据失败:', error);
- throw error;
- }
- }
- /**
- * 获取统一空间数据
- */
- async getUnifiedSpaceData(projectId: string): Promise<any[]> {
- try {
- const projectQuery = new Parse.Query('Project');
- const project = await projectQuery.get(projectId);
-
- const data = project.get('data') || {};
-
- // 优先返回统一空间数据
- if (data.unifiedSpaces && data.unifiedSpaces.length > 0) {
- console.log(`✅ [统一空间管理] 从unifiedSpaces获取到 ${data.unifiedSpaces.length} 个空间`);
- return data.unifiedSpaces;
- }
-
- // 如果没有统一数据,尝试从Product表迁移
- const productSpaces = await this.getProjectProductSpaces(projectId);
- if (productSpaces.length > 0) {
- console.log(`🔄 [统一空间管理] 从Product表迁移 ${productSpaces.length} 个空间到统一存储`);
- const unifiedSpaces = productSpaces.map((space, index) => ({
- id: space.id,
- name: space.name,
- type: space.type,
- area: space.area,
- priority: space.priority,
- status: space.status,
- complexity: space.complexity,
- estimatedBudget: space.estimatedBudget,
- order: index,
- quotation: {
- price: space.estimatedBudget || 0,
- processes: {},
- subtotal: space.estimatedBudget || 0
- },
- requirements: space.requirements || {},
- designerId: space.designerId,
- progress: [],
- createdAt: new Date().toISOString(),
- updatedAt: new Date().toISOString()
- }));
-
- // 保存迁移后的数据
- await this.saveUnifiedSpaceData(projectId, unifiedSpaces);
- return unifiedSpaces;
- }
-
- // 如果都没有,返回空数组
- console.log(`⚠️ [统一空间管理] 项目 ${projectId} 没有找到任何空间数据`);
- return [];
- } catch (error) {
- console.error('❌ [统一空间管理] 获取统一空间数据失败:', error);
- return [];
- }
- }
- /**
- * 将统一空间数据同步到Product表
- */
- private async syncUnifiedSpacesToProducts(projectId: string, unifiedSpaces: any[]): Promise<void> {
- try {
- console.log(`🔄 [统一空间管理] 开始同步统一空间到Product表`);
-
- // 获取现有的Product列表
- const existingProducts = await this.getProjectProductSpaces(projectId);
- const existingById = new Map(existingProducts.map(p => [p.id, p]));
-
- for (const space of unifiedSpaces) {
- const existingProduct = existingById.get(space.id);
-
- if (existingProduct) {
- // 更新现有Product
- await this.updateProductSpace(space.id, {
- name: space.name,
- type: space.type,
- area: space.area,
- priority: space.priority,
- status: space.status,
- complexity: space.complexity,
- estimatedBudget: space.quotation.price,
- requirements: space.requirements,
- designerId: space.designerId
- });
- } else {
- // 创建新Product
- await this.createProductSpace(projectId, {
- name: space.name,
- type: space.type,
- area: space.area,
- priority: space.priority,
- status: space.status,
- complexity: space.complexity,
- estimatedBudget: space.quotation.price,
- requirements: space.requirements,
- designerId: space.designerId,
- order: space.order
- });
- }
- }
-
- console.log(`✅ [统一空间管理] 统一空间同步到Product表完成`);
- } catch (error) {
- console.error('❌ [统一空间管理] 同步统一空间到Product表失败:', error);
- }
- }
- /**
- * 创建初始空间(只创建1-2个默认空间)
- */
- async createInitialSpaces(projectId: string, projectType: '家装' | '工装' = '家装'): Promise<any[]> {
- try {
- console.log(`🏠 [初始空间] 为项目 ${projectId} 创建初始空间,类型: ${projectType}`);
-
- let initialSpaces: any[] = [];
-
- if (projectType === '家装') {
- // 家装项目:只创建客厅和主卧两个空间
- initialSpaces = [
- {
- id: `space_${Date.now()}_1`,
- name: '客厅',
- type: 'living_room',
- area: 0,
- priority: 5,
- status: 'not_started',
- complexity: 'medium',
- estimatedBudget: 300,
- order: 0,
- quotation: {
- price: 300,
- processes: {
- modeling: { enabled: true, price: 100, unit: '张', quantity: 1 },
- softDecor: { enabled: true, price: 100, unit: '张', quantity: 1 },
- rendering: { enabled: true, price: 100, unit: '张', quantity: 1 },
- postProcess: { enabled: false, price: 0, unit: '张', quantity: 1 }
- },
- subtotal: 300
- },
- requirements: {},
- designerId: null,
- progress: [],
- createdAt: new Date().toISOString(),
- updatedAt: new Date().toISOString()
- },
- {
- id: `space_${Date.now()}_2`,
- name: '主卧',
- type: 'bedroom',
- area: 0,
- priority: 5,
- status: 'not_started',
- complexity: 'medium',
- estimatedBudget: 300,
- order: 1,
- quotation: {
- price: 300,
- processes: {
- modeling: { enabled: true, price: 100, unit: '张', quantity: 1 },
- softDecor: { enabled: true, price: 100, unit: '张', quantity: 1 },
- rendering: { enabled: true, price: 100, unit: '张', quantity: 1 },
- postProcess: { enabled: false, price: 0, unit: '张', quantity: 1 }
- },
- subtotal: 300
- },
- requirements: {},
- designerId: null,
- progress: [],
- createdAt: new Date().toISOString(),
- updatedAt: new Date().toISOString()
- }
- ];
- } else {
- // 工装项目:只创建一个主要空间
- initialSpaces = [
- {
- id: `space_${Date.now()}_1`,
- name: '主要空间',
- type: 'other',
- area: 0,
- priority: 5,
- status: 'not_started',
- complexity: 'medium',
- estimatedBudget: 500,
- order: 0,
- quotation: {
- price: 500,
- processes: {
- modeling: { enabled: true, price: 150, unit: '张', quantity: 1 },
- softDecor: { enabled: true, price: 150, unit: '张', quantity: 1 },
- rendering: { enabled: true, price: 150, unit: '张', quantity: 1 },
- postProcess: { enabled: true, price: 50, unit: '张', quantity: 1 }
- },
- subtotal: 500
- },
- requirements: {},
- designerId: null,
- progress: [],
- createdAt: new Date().toISOString(),
- updatedAt: new Date().toISOString()
- }
- ];
- }
-
- // 保存到统一存储
- await this.saveUnifiedSpaceData(projectId, initialSpaces);
-
- console.log(`✅ [初始空间] 已创建 ${initialSpaces.length} 个初始空间`);
- return initialSpaces;
- } catch (error) {
- console.error('❌ [初始空间] 创建初始空间失败:', error);
- throw error;
- }
- }
- /**
- * 数据修复:强制同步当前项目的空间数据到统一存储
- */
- async forceRepairSpaceData(projectId: string): Promise<void> {
- try {
- console.log(`🔧 [数据修复] 开始修复项目 ${projectId} 的空间数据...`);
-
- // 1. 获取项目数据
- const projectQuery = new Parse.Query('Project');
- const project = await projectQuery.get(projectId);
- const data = project.get('data') || {};
-
- // 2. 获取Product表中的空间数据
- const productSpaces = await this.getProjectProductSpaces(projectId);
- console.log(`🔧 [数据修复] Product表中有 ${productSpaces.length} 个空间`);
-
- // 3. 获取报价数据中的空间
- const quotationSpaces = Array.isArray(data.quotation?.spaces) ? data.quotation.spaces : [];
- console.log(`🔧 [数据修复] 报价数据中有 ${quotationSpaces.length} 个空间`);
-
- // 4. 以Product表为准,构建统一空间数据
- const unifiedSpaces = productSpaces.map((space, index) => {
- // 尝试从报价数据中找到对应的空间信息
- const quotationSpace = quotationSpaces.find((q: any) =>
- q.spaceId === space.id ||
- (q.name && space.name && q.name.trim().toLowerCase() === space.name.trim().toLowerCase())
- );
-
- return {
- id: space.id,
- name: space.name,
- type: space.type,
- area: space.area || 0,
- priority: space.priority || 5,
- status: space.status || 'not_started',
- complexity: space.complexity || 'medium',
- estimatedBudget: space.estimatedBudget || 0,
- order: index,
- quotation: {
- price: space.estimatedBudget || 0,
- processes: quotationSpace?.processes || {},
- subtotal: quotationSpace?.subtotal || space.estimatedBudget || 0
- },
- requirements: space.requirements || {},
- designerId: space.designerId || null,
- progress: [],
- createdAt: new Date().toISOString(),
- updatedAt: new Date().toISOString()
- };
- });
-
- // 5. 保存到统一存储
- await this.saveUnifiedSpaceData(projectId, unifiedSpaces);
-
- console.log(`✅ [数据修复] 项目 ${projectId} 空间数据修复完成,共 ${unifiedSpaces.length} 个空间`);
- console.log(`🔧 [数据修复] 修复的空间:`, unifiedSpaces.map(s => s.name));
-
- } catch (error) {
- console.error('❌ [数据修复] 修复空间数据失败:', error);
- throw error;
- }
- }
- /**
- * 调试方法:检查项目的空间数据存储情况
- */
- async debugProjectSpaceData(projectId: string): Promise<void> {
- try {
- console.log(`🔍 [调试] 检查项目 ${projectId} 的空间数据存储情况...`);
-
- // 1. 检查Project.data.unifiedSpaces
- const projectQuery = new Parse.Query('Project');
- const project = await projectQuery.get(projectId);
- const data = project.get('data') || {};
-
- console.log(`📊 [调试] Project.data.unifiedSpaces:`, data.unifiedSpaces?.length || 0, '个空间');
- if (data.unifiedSpaces && data.unifiedSpaces.length > 0) {
- console.log(` - 统一空间列表:`, data.unifiedSpaces.map((s: any) => s.name));
- }
-
- // 2. 检查Project.data.quotation.spaces
- console.log(`📊 [调试] Project.data.quotation.spaces:`, data.quotation?.spaces?.length || 0, '个空间');
- if (data.quotation?.spaces && data.quotation.spaces.length > 0) {
- console.log(` - 报价空间列表:`, data.quotation.spaces.map((s: any) => s.name));
- }
-
- // 3. 检查Product表
- const productSpaces = await this.getProjectProductSpaces(projectId);
- console.log(`📊 [调试] Product表:`, productSpaces.length, '个空间');
- if (productSpaces.length > 0) {
- console.log(` - Product空间列表:`, productSpaces.map(s => s.name));
- }
-
- // 4. 数据一致性检查
- const unifiedCount = data.unifiedSpaces?.length || 0;
- const quotationCount = data.quotation?.spaces?.length || 0;
- const productCount = productSpaces.length;
-
- console.log(`🔍 [调试] 数据一致性检查:`);
- console.log(` - 统一存储: ${unifiedCount} 个`);
- console.log(` - 报价数据: ${quotationCount} 个`);
- console.log(` - Product表: ${productCount} 个`);
-
- if (unifiedCount === quotationCount && quotationCount === productCount) {
- console.log(`✅ [调试] 数据一致性检查通过`);
- } else {
- console.log(`❌ [调试] 数据不一致,需要修复`);
- }
-
- } catch (error) {
- console.error('❌ [调试] 检查项目空间数据失败:', error);
- }
- }
- }
|