|
|
@@ -105,8 +105,10 @@ export class QuotationEditorComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
'建筑类': ['门头', '小型单体', '大型单体', '鸟瞰']
|
|
|
};
|
|
|
|
|
|
- // 产品添加模态框状态
|
|
|
+ // 产品添加/编辑模态框状态
|
|
|
showAddProductModal: boolean = false;
|
|
|
+ isEditMode: boolean = false; // 是否为编辑模式
|
|
|
+ editingProductId: string = ''; // 正在编辑的产品ID
|
|
|
newProduct: any = {
|
|
|
isCustom: false,
|
|
|
sceneName: '',
|
|
|
@@ -937,14 +939,55 @@ export class QuotationEditorComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
openAddProductModal(): void {
|
|
|
// 重置表单
|
|
|
this.resetNewProductForm();
|
|
|
+ this.isEditMode = false;
|
|
|
+ this.editingProductId = '';
|
|
|
this.showAddProductModal = true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 关闭添加产品模态框
|
|
|
+ * 打开编辑产品模态框
|
|
|
+ */
|
|
|
+ openEditProductModal(productId: string): void {
|
|
|
+ const product = this.products.find(p => p.id === productId);
|
|
|
+ if (!product) return;
|
|
|
+
|
|
|
+ // 预填充产品数据
|
|
|
+ const space = product.get('space') || {};
|
|
|
+ const quotation = product.get('quotation') || {};
|
|
|
+ const adjustments = quotation.adjustments || {};
|
|
|
+
|
|
|
+ // 判断是否为自定义名称
|
|
|
+ const presetScenes = this.getPresetScenes();
|
|
|
+ const isPreset = presetScenes.includes(product.get('productName'));
|
|
|
+
|
|
|
+ this.newProduct = {
|
|
|
+ isCustom: !isPreset,
|
|
|
+ sceneName: isPreset ? product.get('productName') : '',
|
|
|
+ productName: product.get('productName'),
|
|
|
+ spaceType: space.spaceType || this.getDefaultSpaceType(),
|
|
|
+ styleLevel: space.styleLevel || '基础风格组',
|
|
|
+ businessType: space.businessType || '办公空间',
|
|
|
+ architectureType: space.architectureType || '门头',
|
|
|
+ adjustments: {
|
|
|
+ extraFunction: adjustments.extraFunction || 0,
|
|
|
+ complexity: adjustments.complexity || 0,
|
|
|
+ design: adjustments.design || false,
|
|
|
+ panoramic: adjustments.panoramic || false
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.isEditMode = true;
|
|
|
+ this.editingProductId = productId;
|
|
|
+ this.showAddProductModal = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭添加/编辑产品模态框
|
|
|
*/
|
|
|
closeAddProductModal(): void {
|
|
|
this.showAddProductModal = false;
|
|
|
+ this.isEditMode = false;
|
|
|
+ this.editingProductId = '';
|
|
|
this.resetNewProductForm();
|
|
|
}
|
|
|
|
|
|
@@ -1096,7 +1139,7 @@ export class QuotationEditorComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 确认添加产品
|
|
|
+ * 确认添加/编辑产品
|
|
|
*/
|
|
|
async confirmAddProduct(): Promise<void> {
|
|
|
if (!this.isNewProductValid()) {
|
|
|
@@ -1105,44 +1148,163 @@ export class QuotationEditorComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- const productName = this.newProduct.isCustom
|
|
|
- ? this.newProduct.productName
|
|
|
- : this.newProduct.sceneName;
|
|
|
+ if (this.isEditMode) {
|
|
|
+ await this.updateExistingProduct();
|
|
|
+ } else {
|
|
|
+ await this.createNewProduct();
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(this.isEditMode ? '编辑产品失败:' : '添加产品失败:', error);
|
|
|
+ alert(this.isEditMode ? '编辑产品失败,请重试' : '添加产品失败,请重试');
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- const config: any = {
|
|
|
- spaceType: this.newProduct.spaceType
|
|
|
- };
|
|
|
+ /**
|
|
|
+ * 创建新产品
|
|
|
+ */
|
|
|
+ private async createNewProduct(): Promise<void> {
|
|
|
+ const productName = this.newProduct.isCustom
|
|
|
+ ? this.newProduct.productName
|
|
|
+ : this.newProduct.sceneName;
|
|
|
+
|
|
|
+ const config: any = {
|
|
|
+ spaceType: this.newProduct.spaceType
|
|
|
+ };
|
|
|
|
|
|
+ if (this.projectInfo.projectType === '家装') {
|
|
|
+ config.styleLevel = this.newProduct.styleLevel;
|
|
|
+ } else if (this.projectInfo.projectType === '工装') {
|
|
|
+ config.businessType = this.newProduct.businessType;
|
|
|
+ } else if (this.projectInfo.projectType === '建筑类') {
|
|
|
+ config.architectureType = this.newProduct.architectureType;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建产品
|
|
|
+ const product = await this.createProductWithAdjustments(productName, config);
|
|
|
+
|
|
|
+ if (product) {
|
|
|
+ // 重新加载产品列表
|
|
|
+ await this.loadProjectProducts();
|
|
|
+
|
|
|
+ // 重新生成报价
|
|
|
+ await this.generateQuotationFromProducts();
|
|
|
+
|
|
|
+ // 关闭模态框
|
|
|
+ this.closeAddProductModal();
|
|
|
+
|
|
|
+ alert(`成功添加产品: ${productName}`);
|
|
|
+ } else {
|
|
|
+ throw new Error('创建产品失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新现有产品
|
|
|
+ */
|
|
|
+ private async updateExistingProduct(): Promise<void> {
|
|
|
+ const product = this.products.find(p => p.id === this.editingProductId);
|
|
|
+ if (!product) {
|
|
|
+ throw new Error('找不到要编辑的产品');
|
|
|
+ }
|
|
|
+
|
|
|
+ const productName = this.newProduct.isCustom
|
|
|
+ ? this.newProduct.productName
|
|
|
+ : this.newProduct.sceneName;
|
|
|
+
|
|
|
+ // 更新产品名称和类型
|
|
|
+ product.set('productName', productName);
|
|
|
+ product.set('productType', this.inferProductType(productName));
|
|
|
+
|
|
|
+ // 确定配置
|
|
|
+ const spaceType = this.newProduct.spaceType;
|
|
|
+ const styleLevel = this.newProduct.styleLevel;
|
|
|
+ const businessType = this.newProduct.businessType;
|
|
|
+ const architectureType = this.newProduct.architectureType;
|
|
|
+
|
|
|
+ // 更新空间信息
|
|
|
+ const space = product.get('space') || {};
|
|
|
+ space.spaceName = productName;
|
|
|
+ space.spaceType = spaceType;
|
|
|
+ space.styleLevel = styleLevel;
|
|
|
+ space.businessType = businessType;
|
|
|
+ space.architectureType = architectureType;
|
|
|
+ product.set('space', space);
|
|
|
+
|
|
|
+ // 重新计算基础价格
|
|
|
+ let basePrice = this.calculateBasePrice({
|
|
|
+ priceLevel: this.projectInfo.priceLevel,
|
|
|
+ projectType: this.projectInfo.projectType,
|
|
|
+ renderType: this.projectInfo.renderType,
|
|
|
+ spaceType: spaceType,
|
|
|
+ styleLevel: styleLevel,
|
|
|
+ businessType: businessType,
|
|
|
+ architectureType: architectureType
|
|
|
+ });
|
|
|
+
|
|
|
+ // 应用加价规则
|
|
|
+ let finalPrice = basePrice;
|
|
|
+ const adjustments = this.newProduct.adjustments;
|
|
|
+
|
|
|
+ // 功能区加价
|
|
|
+ if (adjustments.extraFunction > 0) {
|
|
|
if (this.projectInfo.projectType === '家装') {
|
|
|
- config.styleLevel = this.newProduct.styleLevel;
|
|
|
+ finalPrice += adjustments.extraFunction * 100;
|
|
|
} else if (this.projectInfo.projectType === '工装') {
|
|
|
- config.businessType = this.newProduct.businessType;
|
|
|
- } else if (this.projectInfo.projectType === '建筑类') {
|
|
|
- config.architectureType = this.newProduct.architectureType;
|
|
|
+ finalPrice += adjustments.extraFunction * 400;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- // 创建产品
|
|
|
- const product = await this.createProductWithAdjustments(productName, config);
|
|
|
+ // 造型复杂度加价
|
|
|
+ if (adjustments.complexity > 0) {
|
|
|
+ finalPrice += adjustments.complexity;
|
|
|
+ }
|
|
|
|
|
|
- if (product) {
|
|
|
- // 重新加载产品列表
|
|
|
- await this.loadProjectProducts();
|
|
|
+ // 设计服务倍增
|
|
|
+ if (adjustments.design) {
|
|
|
+ finalPrice *= 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 全景渲染倍增(仅工装)
|
|
|
+ if (this.projectInfo.projectType === '工装' && adjustments.panoramic) {
|
|
|
+ finalPrice *= 2;
|
|
|
+ }
|
|
|
|
|
|
- // 重新生成报价
|
|
|
- await this.generateQuotationFromProducts();
|
|
|
+ finalPrice = Math.round(finalPrice);
|
|
|
+
|
|
|
+ // 更新报价信息
|
|
|
+ const quotation = product.get('quotation') || {};
|
|
|
+ quotation.basePrice = Math.round(basePrice);
|
|
|
+ quotation.price = finalPrice;
|
|
|
+ quotation.adjustments = {
|
|
|
+ extraFunction: adjustments.extraFunction,
|
|
|
+ complexity: adjustments.complexity,
|
|
|
+ design: adjustments.design,
|
|
|
+ panoramic: adjustments.panoramic
|
|
|
+ };
|
|
|
+ quotation.breakdown = this.calculatePriceBreakdown(finalPrice);
|
|
|
+ product.set('quotation', quotation);
|
|
|
+
|
|
|
+ // 保存产品
|
|
|
+ await product.save();
|
|
|
+
|
|
|
+ // 更新报价中的空间数据
|
|
|
+ const spaceData = this.quotation.spaces.find((s: any) => s.productId === this.editingProductId);
|
|
|
+ if (spaceData) {
|
|
|
+ spaceData.name = productName;
|
|
|
+ // 重新生成该空间的分配
|
|
|
+ spaceData.processes = this.generateDefaultProcesses(finalPrice);
|
|
|
+ }
|
|
|
|
|
|
- // 关闭模态框
|
|
|
- this.closeAddProductModal();
|
|
|
+ // 重新加载产品列表
|
|
|
+ await this.loadProjectProducts();
|
|
|
|
|
|
- alert(`成功添加产品: ${productName}`);
|
|
|
- } else {
|
|
|
- throw new Error('创建产品失败');
|
|
|
- }
|
|
|
+ // 重新生成报价
|
|
|
+ await this.generateQuotationFromProducts();
|
|
|
|
|
|
- } catch (error) {
|
|
|
- console.error('添加产品失败:', error);
|
|
|
- alert('添加产品失败,请重试');
|
|
|
- }
|
|
|
+ // 关闭模态框
|
|
|
+ this.closeAddProductModal();
|
|
|
+
|
|
|
+ alert(`成功更新产品: ${productName}`);
|
|
|
}
|
|
|
|
|
|
/**
|