# 映三色报价系统PRD - 报价自动分配与智能计算 ## 一、功能概述 ### 1.1 功能定位 映三色视觉设计表现公司的智能报价系统,支持三级报价体系(一级老客户、二级中端组、三级高端组),实现以空间为单位的独立设计产品报价管理,自动计算内部执行分配。 ### 1.2 核心价值 - **空间独立报价**: 每个空间都是独立的设计产品服务,有独立的报价和分配 - **智能预设场景**: 根据项目类型和场景提供预设选项,提高报价效率 - **自动分配计算**: 基于报价总额自动计算内部执行三阶段分配(10%-40%-50%) - **精准价格控制**: 所有价格均为整数,无小数点,便于财务核算 - **规则驱动**: 严格遵循docs/data/quotation.md中的定价标准 --- ## 二、报价规则体系 ### 2.1 三级报价体系 | 报价等级 | 适用对象 | 价格水平 | 服务定位 | |---------|---------|---------|---------| | **一级** | 老客户 | 最低 | 标准服务,维护老客户关系 | | **二级** | 中端客户 | 中等 | 中端市场,平衡性价比 | | **三级** | 高端客户 | 最高 | 高端市场,优质服务 | ### 2.2 家装区报价规则 #### 2.2.1 风格等级分类 | 风格等级 | 风格类型 | |---------|---------| | **基础风格组** | 现代、北欧、简约、后现代、工业风 | | **中级风格组** | 轻奢、日式、新中式 | | **高级风格组** | 简欧、古典中式、欧式、美式、简美、轻法 | | **顶级风格组** | 古典欧式、古典美式、纯法式 | #### 2.2.2 空间类型与基础定价(一级报价-静态单张示例) | 空间类型 | 基础风格组 | 中级风格组 | 高级风格组 | 顶级风格组 | |---------|-----------|-----------|-----------|-----------| | **平层客餐厅** | 300元 | 350元 | 400元 | 500元 | | **跃层客餐厅** | 400元 | 450元 | 500元 | 600元 | | **挑空客餐厅** | 600元 | 700元 | 800元 | 900元 | | **卧室** | 300元 | 300元 | 300元 | 300元 | #### 2.2.3 家装浮动加价规则 1. **功能区加价** - 客餐厅空间只出一张:+100元 - 每增加一个功能区:+100元 - 卧室每增加一个功能区:+100元 2. **造型复杂度加价** - 立面和吊顶根据参考图制作,考虑立面造型复杂:+100至200元 3. **设计服务加价** - 需要我们设计(非提供参考图):原价×2 4. **卧室特殊规则** - 卧室每增加一个功能区:+100元 - 根据参考图建模:+100元 ### 2.3 工装区报价规则 #### 2.3.1 场景分类与定价(一级报价-静态单张) | 空间类型 | 门厅空间 | 封闭空间 | |---------|---------|---------| | 办公空间 | 600元 | 400元 | | 商业空间 | 600元 | 500元 | | 娱乐空间 | 600元 | 500元 | | 酒店餐厅 | 600元 | 500元 | | 公共空间 | 600元 | 600元 | #### 2.3.2 工装浮动加价规则 1. **功能区加价**: 每增加一个功能区:+400元 2. **造型复杂度加价**: 立面和吊顶根据参考图制作,考虑立面造型复杂:+100至200元 3. **设计服务加价**: 需要我们设计:原价×2 4. **全景输出**: 需要全景渲染:原价×2 ### 2.4 建筑类报价规则 #### 2.4.1 场景分类与定价(一级报价) | 场景类型 | 价格 | |---------|------| | 门头 | 700元 | | 小型单体 | 1000元 | | 大型单体 | 1500元 | | 鸟瞰 | 2000元 | --- ## 三、核心功能设计 ### 3.1 空间独立设计产品管理 **设计原则**: 每个空间都是一个独立的设计产品服务,有独立的: - 产品名称(空间名称) - 产品类型(客厅、卧室、厨房等) - 报价配置(基础价格 + 加价项) - 工序明细(建模、软装、渲染、后期) - 内部分配(建模阶段、软装渲染、公司分配) ### 3.2 智能添加产品功能 #### 3.2.1 添加产品流程 1. 点击"添加产品"按钮 2. 弹出产品配置对话框/模态框 3. 选择配置项: - **项目类型**: 家装 / 工装 / 建筑类 - **渲染类型**: 静态单张 / 360全景(家装/工装) - **空间场景**: 根据项目类型显示预设场景 - **风格等级**: (家装专属)基础/中级/高级/顶级风格组 - **业态类型**: (工装专属)办公/商业/娱乐/酒店餐厅/公共 - **空间类型**: (家装)平层/跃层/挑空/卧室,(工装)门厅/封闭 - **自定义名称**: 可修改默认名称 4. 系统自动计算基础价格并显示 5. 确认后创建产品 #### 3.2.2 预设场景列表 **家装预设场景**: - 客厅、餐厅、主卧、次卧、儿童房、书房、厨房、卫生间、阳台 **工装预设场景**: - 大堂、接待区、会议室、办公区、休息区、展示区、洽谈区 **建筑类预设场景**: - 门头、小型单体、大型单体、鸟瞰 **场景选择逻辑**: - 如果用户选择的场景在预设列表中,直接使用预设名称和报价规则 - 如果用户选择"自定义",则需要手动填写名称,系统匹配最接近的报价规则 ### 3.3 基础价格计算(calculateBasePrice) #### 3.3.1 计算逻辑 ```typescript function calculateBasePrice(config: { priceLevel: '一级' | '二级' | '三级'; projectType: '家装' | '工装' | '建筑类'; renderType: '静态单张' | '360全景'; spaceType: string; // 平层/跃层/挑空/卧室 或 门厅空间/封闭空间 styleLevel?: string; // 家装:基础风格组/中级风格组等 businessType?: string; // 工装:办公空间/商业空间等 architectureType?: string; // 建筑类:门头/小型单体等 }): number { // 根据报价规则表精确查找价格 // 每个空间都是独立的设计产品服务,有独立的基础价格 } ``` #### 3.3.2 示例计算 **示例1: 家装平层客厅(一级-现代风格-静态单张)** ``` 基础价格 = 300元(基础风格组-平层) ``` **示例2: 家装跃层客厅(三级-古典欧式-360全景)** ``` 基础价格 = 1700元(顶级风格组-跃层-360全景) ``` **示例3: 工装办公门厅(二级-静态单张)** ``` 基础价格 = 700元(二级-办公空间-门厅空间-静态单张) ``` ### 3.4 内部执行分配规则 #### 3.4.1 分配比例 基于报价总价,自动按固定比例拆分为内部执行三个阶段: | 分配类型 | 占比 | 说明 | 用途 | |---------|------|------|------| | **建模阶段** | 10% | 3D模型构建 | 支付给建模设计师的费用 | | **软装渲染** | 40% | 软装搭配+效果图渲染 | 支付给软装和渲染设计师的费用 | | **公司分配** | 50% | 公司运营与利润 | 公司管理成本、平台服务费、利润等 | #### 3.4.2 分配计算公式 ```typescript 建模阶段金额 = Math.round(报价总价 × 10%) 软装渲染金额 = Math.round(报价总价 × 40%) 公司分配金额 = Math.round(报价总价 × 50%) ``` **注意**: 所有金额使用 `Math.round()` 四舍五入到整数,确保无小数。 #### 3.4.3 分配示例 **示例1: 厨房空间** ``` 报价总价: ¥900 建模阶段: ¥900 × 10% = ¥90 软装渲染: ¥900 × 40% = ¥360 公司分配: ¥900 × 50% = ¥450 ``` **示例2: 客厅空间** ``` 报价总价: ¥1,500 建模阶段: ¥1,500 × 10% = ¥150 软装渲染: ¥1,500 × 40% = ¥600 公司分配: ¥1,500 × 50% = ¥750 ``` --- ## 四、数据结构设计 ### 4.1 产品(Product)数据结构 ```typescript interface Product { id: string; project: Pointer; productName: string; // 产品名称(空间名称) productType: string; // 产品类型(living_room, bedroom等) // 空间信息 space: { spaceName: string; area: number; dimensions: { length: number; width: number; height: number }; spaceType: string; // 平层/跃层/挑空等 styleLevel?: string; // 风格等级(家装) businessType?: string; // 业态类型(工装) architectureType?: string; // 建筑类型 complexity: 'low' | 'medium' | 'high'; }; // 报价信息 quotation: { priceLevel: '一级' | '二级' | '三级'; basePrice: number; // 基础价格(整数) adjustments: { extraFunction?: number; // 额外功能区数量 complexity?: number; // 造型复杂度加价 design?: boolean; // 是否需要设计服务 panoramic?: boolean; // 是否全景渲染 }; finalPrice: number; // 最终价格(整数) // 工序明细 processes: { modeling: { enabled: boolean; price: number; quantity: number; }; softDecor: { enabled: boolean; price: number; quantity: number; }; rendering: { enabled: boolean; price: number; quantity: number; }; postProcess: { enabled: boolean; price: number; quantity: number; }; }; // 内部分配(整数) allocation: { modeling: number; decoration: number; company: number; }; status: 'draft' | 'confirmed' | 'modified'; validUntil: Date; }; // 需求信息 requirements: { colorRequirement: any; materialRequirement: any; lightingRequirement: any; specificRequirements: string[]; }; status: 'not_started' | 'in_progress' | 'completed'; profile?: Pointer; // 负责的设计师 } ``` ### 4.2 项目(Project)报价汇总结构 ```typescript interface ProjectQuotation { spaces: Array<{ name: string; productId: string; processes: ProcessConfig; subtotal: number; // 该空间小计(整数) }>; total: number; // 项目总价(整数) // 产品占比明细 spaceBreakdown: Array<{ spaceName: string; spaceId: string; amount: number; // 整数 percentage: number; // 百分比 }>; // 内部执行分配(整数) allocation: { modeling: { amount: number; percentage: 10; description: '3D模型构建'; }; decoration: { amount: number; percentage: 40; description: '软装搭配+效果图渲染'; }; company: { amount: number; percentage: 50; description: '公司运营与利润'; }; updatedAt: Date; }; generatedAt: Date; validUntil: Date; } ``` --- ## 五、UI/UX设计 ### 5.1 添加产品组件 #### 5.1.1 组件结构 ```html
``` ### 5.2 报价编辑器主界面 #### 5.2.1 产品卡片展示 ```html

{{ product.productName }}

{{ product.space.spaceType }} @if (product.space.styleLevel) { {{ product.space.styleLevel }} } {{ getStatusText(product.status) }}
¥{{ getProductFinalPrice(product) }}
基础 ¥{{ product.quotation.basePrice }}
@if (isExpanded(product)) {
空间信息
面积 {{ product.space.area || 0 }}㎡
复杂度 {{ product.space.complexity }}
工序明细
@for (processType of processTypes; track processType.key) {
@if (isProcessEnabled(product, processType.key)) {
小计: ¥{{ calculateProcessSubtotal(product, processType.key) }}
}
}
内部分配
建模阶段 (10%) ¥{{ product.quotation.allocation.modeling }}
软装渲染 (40%) ¥{{ product.quotation.allocation.decoration }}
公司分配 (50%) ¥{{ product.quotation.allocation.company }}
}
``` ### 5.3 报价汇总区域 ```html

报价汇总

@if (showBreakdown) {
@for (item of quotation.spaceBreakdown; track item.spaceId) {
{{ item.spaceName }} ¥{{ item.amount }} {{ item.percentage }}%
}
}

内部执行分配

@if (showAllocation && quotation.allocation) {
...
建模阶段

3D模型构建

10% ¥{{ quotation.allocation.modeling.amount }}
...
软装渲染

软装搭配+效果图渲染

40% ¥{{ quotation.allocation.decoration.amount }}
...
公司分配

公司运营与利润

50% ¥{{ quotation.allocation.company.amount }}
内部执行分配为系统自动计算,基于报价总额按固定比例拆分,所有金额均为整数
}
报价总额 ¥{{ quotation.total }}
生成于 {{ quotation.generatedAt | date:'yyyy-MM-dd HH:mm' }} 有效期至 {{ quotation.validUntil | date:'yyyy-MM-dd' }}
``` --- ## 六、移动端适配 ### 6.1 响应式设计要点 1. **卡片布局**: 移动端单列显示,宽度100% 2. **工序网格**: 移动端改为单列,避免横向滚动 3. **表单元素**: 增大触摸区域,最小44×44px 4. **字体大小**: 移动端基础字号14px,标题16-18px 5. **间距优化**: 移动端适当增加卡片间距,提升点击体验 ### 6.2 移动端专属优化 ```scss @media (max-width: 768px) { // 产品卡片 .product-card { margin-bottom: 16px; .product-header { flex-direction: column; align-items: flex-start; padding: 16px; .product-pricing { width: 100%; margin-top: 12px; display: flex; justify-content: space-between; } } } // 工序网格 .process-grid { grid-template-columns: 1fr; } // 分配卡片 .allocation-card { flex-direction: column; align-items: flex-start; .allocation-values { width: 100%; flex-direction: row; justify-content: space-between; margin-top: 12px; padding-top: 12px; border-top: 1px solid rgba(0,0,0,0.05); } } // 添加产品模态框 .add-product-modal { width: 100%; max-height: 90vh; border-radius: 16px 16px 0 0; .scene-grid { grid-template-columns: repeat(3, 1fr); } } } ``` --- ## 七、技术实现要点 ### 7.1 关键方法实现 #### 7.1.1 calculateBasePrice(重构版) ```typescript /** * 计算空间基础价格 * 严格按照 docs/data/quotation.md 规则 */ private calculateBasePrice(config: ProductConfig): number { const { priceLevel, projectType, renderType, spaceType, styleLevel, businessType, architectureType } = config; // 使用quotation-rules.ts中的getBasePrice函数 const basePrice = getBasePrice( priceLevel, projectType, renderType, spaceType, styleLevel, businessType, architectureType ); // 确保返回整数 return Math.round(basePrice); } ``` #### 7.1.2 整数价格确保 ```typescript /** * 确保所有价格计算结果都是整数 */ private ensureIntegerPrices(quotation: any) { // 工序价格整数化 for (const space of quotation.spaces) { for (const processKey of Object.keys(space.processes)) { const process = space.processes[processKey]; process.price = Math.round(process.price); process.quantity = Math.round(process.quantity); } } // 总价整数化 quotation.total = Math.round(quotation.total); // 分配金额整数化 if (quotation.allocation) { quotation.allocation.modeling.amount = Math.round(quotation.allocation.modeling.amount); quotation.allocation.decoration.amount = Math.round(quotation.allocation.decoration.amount); quotation.allocation.company.amount = Math.round(quotation.allocation.company.amount); } } ``` --- ## 八、测试用例 ### 8.1 基础价格计算测试 ```typescript test('家装平层基础风格组一级报价应为300元', () => { const price = calculateBasePrice({ priceLevel: '一级', projectType: '家装', renderType: '静态单张', spaceType: '平层', styleLevel: '基础风格组' }); expect(price).toBe(300); }); test('工装办公门厅三级报价应为900元', () => { const price = calculateBasePrice({ priceLevel: '三级', projectType: '工装', renderType: '静态单张', spaceType: '门厅空间', businessType: '办公空间' }); expect(price).toBe(900); }); ``` ### 8.2 分配计算测试 ```typescript test('900元报价应分配为90-360-450', () => { const allocation = calculateAllocation(900); expect(allocation.modeling.amount).toBe(90); expect(allocation.decoration.amount).toBe(360); expect(allocation.company.amount).toBe(450); }); test('分配金额应全部为整数', () => { const allocation = calculateAllocation(12345); expect(allocation.modeling.amount % 1).toBe(0); expect(allocation.decoration.amount % 1).toBe(0); expect(allocation.company.amount % 1).toBe(0); }); ``` --- ## 九、FAQ ### Q1: 为什么每个空间都是独立的设计产品? **A:** 按照业务规则,每个空间(客厅、卧室、厨房等)都是一个独立的设计图服务,有独立的报价、工序和分配。这样可以精准控制每个空间的成本和利润。 ### Q2: 如何确保价格都是整数? **A:** 所有涉及价格计算的地方都使用 `Math.round()` 进行四舍五入,包括基础价格、工序价格、总价、分配金额等。 ### Q3: 预设场景列表可以自定义吗? **A:** 可以。预设场景列表定义在组件配置中,管理员可以根据实际业务需求调整。如果用户选择"自定义",可以手动输入空间名称。 ### Q4: 报价规则如何更新? **A:** 报价规则定义在 `quotation-rules.ts` 配置文件和 `docs/data/quotation.md` 文档中。更新时需同步修改两处,确保代码和文档一致。 --- **文档版本**: v2.0 **创建日期**: 2025-10-25 **更新日期**: 2025-10-25 **作者**: Claude Code AI **审核状态**: 待审核