ai-quotation.service.ts 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. import { Injectable } from '@angular/core';
  2. import { Observable, of, delay } from 'rxjs';
  3. export interface AIQuotationParams {
  4. area: number;
  5. style: string;
  6. level: string;
  7. specialRequirements?: string;
  8. }
  9. export interface AIQuotationItem {
  10. category: string;
  11. name: string;
  12. quantity: number;
  13. unit: string;
  14. unitPrice: number;
  15. description?: string;
  16. }
  17. export interface AIQuotationResult {
  18. items: AIQuotationItem[];
  19. totalAmount: number;
  20. suggestions?: string[];
  21. }
  22. @Injectable({
  23. providedIn: 'root'
  24. })
  25. export class AIQuotationService {
  26. // 装修风格价格系数
  27. private styleMultipliers: { [key: string]: number } = {
  28. '现代简约': 1.0,
  29. '北欧风格': 1.1,
  30. '中式风格': 1.3,
  31. '欧式风格': 1.4,
  32. '美式风格': 1.2,
  33. '工业风格': 1.1,
  34. '地中海风格': 1.2,
  35. '日式风格': 1.15
  36. };
  37. // 装修档次价格系数
  38. private levelMultipliers: { [key: string]: number } = {
  39. '经济型': 0.8,
  40. '舒适型': 1.0,
  41. '豪华型': 1.5,
  42. '奢华型': 2.0
  43. };
  44. // 基础报价模板
  45. private baseQuotationTemplate: AIQuotationItem[] = [
  46. {
  47. category: '客餐厅',
  48. name: '墙面乳胶漆',
  49. quantity: 1,
  50. unit: '㎡',
  51. unitPrice: 35,
  52. description: '包含基层处理、刮腻子、刷底漆面漆'
  53. },
  54. {
  55. category: '客餐厅',
  56. name: '地面瓷砖铺贴',
  57. quantity: 1,
  58. unit: '㎡',
  59. unitPrice: 80,
  60. description: '包含瓷砖、水泥沙浆、人工费'
  61. },
  62. {
  63. category: '客餐厅',
  64. name: '吊顶造型',
  65. quantity: 1,
  66. unit: '㎡',
  67. unitPrice: 120,
  68. description: '石膏板吊顶,包含龙骨、石膏板、乳胶漆'
  69. },
  70. {
  71. category: '厨房',
  72. name: '厨房墙地砖',
  73. quantity: 1,
  74. unit: '㎡',
  75. unitPrice: 90,
  76. description: '防滑地砖、墙面瓷砖铺贴'
  77. },
  78. {
  79. category: '厨房',
  80. name: '橱柜定制',
  81. quantity: 1,
  82. unit: '延米',
  83. unitPrice: 1200,
  84. description: '包含地柜、吊柜、台面、五金配件'
  85. },
  86. {
  87. category: '卫生间',
  88. name: '卫生间防水',
  89. quantity: 1,
  90. unit: '㎡',
  91. unitPrice: 60,
  92. description: '聚氨酯防水涂料,包工包料'
  93. },
  94. {
  95. category: '卫生间',
  96. name: '卫浴洁具',
  97. quantity: 1,
  98. unit: '套',
  99. unitPrice: 2500,
  100. description: '马桶、洗手盆、花洒、龙头等'
  101. },
  102. {
  103. category: '卧室',
  104. name: '卧室地板',
  105. quantity: 1,
  106. unit: '㎡',
  107. unitPrice: 150,
  108. description: '复合地板,包含踢脚线安装'
  109. },
  110. {
  111. category: '卧室',
  112. name: '衣柜定制',
  113. quantity: 1,
  114. unit: '㎡',
  115. unitPrice: 800,
  116. description: '整体衣柜,包含五金配件'
  117. },
  118. {
  119. category: '水电改造',
  120. name: '水电改造',
  121. quantity: 1,
  122. unit: '项',
  123. unitPrice: 8000,
  124. description: '全屋水电线路改造,包含材料人工'
  125. }
  126. ];
  127. constructor() { }
  128. /**
  129. * 生成AI智能报价
  130. * @param params 报价参数
  131. * @returns 报价结果
  132. */
  133. generateQuotation(params: AIQuotationParams): Observable<AIQuotationResult> {
  134. // 模拟AI处理延迟
  135. return of(this.calculateQuotation(params)).pipe(
  136. delay(2000) // 模拟2秒的AI处理时间
  137. );
  138. }
  139. /**
  140. * 计算报价
  141. * @param params 报价参数
  142. * @returns 报价结果
  143. */
  144. private calculateQuotation(params: AIQuotationParams): AIQuotationResult {
  145. const { area, style, level, specialRequirements } = params;
  146. // 获取价格系数
  147. const styleMultiplier = this.styleMultipliers[style] || 1.0;
  148. const levelMultiplier = this.levelMultipliers[level] || 1.0;
  149. // 计算各项目数量和价格
  150. const items: AIQuotationItem[] = this.baseQuotationTemplate.map(template => {
  151. let quantity = area;
  152. let unitPrice = template.unitPrice * styleMultiplier * levelMultiplier;
  153. // 根据项目类型调整数量
  154. switch (template.category) {
  155. case '客餐厅':
  156. quantity = Math.round(area * 0.4); // 客餐厅占40%面积
  157. break;
  158. case '厨房':
  159. if (template.name.includes('橱柜')) {
  160. quantity = Math.round(area * 0.08); // 橱柜按延米计算
  161. } else {
  162. quantity = Math.round(area * 0.1); // 厨房占10%面积
  163. }
  164. break;
  165. case '卫生间':
  166. if (template.name.includes('洁具')) {
  167. quantity = Math.ceil(area / 50); // 每50㎡一套洁具
  168. } else {
  169. quantity = Math.round(area * 0.08); // 卫生间占8%面积
  170. }
  171. break;
  172. case '卧室':
  173. if (template.name.includes('衣柜')) {
  174. quantity = Math.round(area * 0.15); // 衣柜按投影面积
  175. } else {
  176. quantity = Math.round(area * 0.3); // 卧室占30%面积
  177. }
  178. break;
  179. case '水电改造':
  180. quantity = 1; // 水电改造按项目计算
  181. unitPrice = area * 80 * levelMultiplier; // 按面积计算水电改造费用
  182. break;
  183. }
  184. return {
  185. ...template,
  186. quantity: Math.max(1, quantity),
  187. unitPrice: Math.round(unitPrice)
  188. };
  189. });
  190. // 根据特殊需求调整报价
  191. if (specialRequirements) {
  192. this.adjustForSpecialRequirements(items, specialRequirements);
  193. }
  194. // 计算总金额
  195. const totalAmount = items.reduce((sum, item) => sum + (item.quantity * item.unitPrice), 0);
  196. // 生成建议
  197. const suggestions = this.generateSuggestions(params, totalAmount);
  198. return {
  199. items,
  200. totalAmount: Math.round(totalAmount),
  201. suggestions
  202. };
  203. }
  204. /**
  205. * 根据特殊需求调整报价
  206. * @param items 报价项目
  207. * @param specialRequirements 特殊需求
  208. */
  209. private adjustForSpecialRequirements(items: AIQuotationItem[], specialRequirements: string): void {
  210. const requirements = specialRequirements.toLowerCase();
  211. // 智能家居需求
  212. if (requirements.includes('智能') || requirements.includes('智能家居')) {
  213. items.push({
  214. category: '智能家居',
  215. name: '智能家居系统',
  216. quantity: 1,
  217. unit: '套',
  218. unitPrice: 15000,
  219. description: '包含智能开关、智能门锁、智能窗帘等'
  220. });
  221. }
  222. // 中央空调需求
  223. if (requirements.includes('中央空调') || requirements.includes('空调')) {
  224. items.push({
  225. category: '暖通设备',
  226. name: '中央空调系统',
  227. quantity: 1,
  228. unit: '套',
  229. unitPrice: 25000,
  230. description: '包含主机、管道、出风口等'
  231. });
  232. }
  233. // 地暖需求
  234. if (requirements.includes('地暖') || requirements.includes('采暖')) {
  235. items.push({
  236. category: '暖通设备',
  237. name: '地暖系统',
  238. quantity: 1,
  239. unit: '套',
  240. unitPrice: 18000,
  241. description: '包含地暖管道、分水器、温控器等'
  242. });
  243. }
  244. // 新风系统需求
  245. if (requirements.includes('新风') || requirements.includes('通风')) {
  246. items.push({
  247. category: '暖通设备',
  248. name: '新风系统',
  249. quantity: 1,
  250. unit: '套',
  251. unitPrice: 12000,
  252. description: '包含新风主机、管道、出风口等'
  253. });
  254. }
  255. // 定制家具需求
  256. if (requirements.includes('定制') || requirements.includes('家具')) {
  257. items.push({
  258. category: '定制家具',
  259. name: '全屋定制家具',
  260. quantity: 1,
  261. unit: '套',
  262. unitPrice: 30000,
  263. description: '包含鞋柜、电视柜、书柜等定制家具'
  264. });
  265. }
  266. }
  267. /**
  268. * 生成装修建议
  269. * @param params 报价参数
  270. * @param totalAmount 总金额
  271. * @returns 建议列表
  272. */
  273. private generateSuggestions(params: AIQuotationParams, totalAmount: number): string[] {
  274. const suggestions: string[] = [];
  275. const { area, style, level } = params;
  276. // 预算建议
  277. const budgetPerSqm = totalAmount / area;
  278. if (budgetPerSqm > 2000) {
  279. suggestions.push('当前预算较高,建议优化材料选择以控制成本');
  280. } else if (budgetPerSqm < 800) {
  281. suggestions.push('当前预算偏低,建议适当提升材料档次以保证质量');
  282. }
  283. // 风格建议
  284. if (style === '现代简约') {
  285. suggestions.push('现代简约风格注重功能性,建议选择简洁大方的材料和色彩');
  286. } else if (style === '中式风格') {
  287. suggestions.push('中式风格建议选用实木材料,注重对称和层次感');
  288. } else if (style === '北欧风格') {
  289. suggestions.push('北欧风格建议使用浅色系,注重自然光线和简约线条');
  290. }
  291. // 档次建议
  292. if (level === '经济型') {
  293. suggestions.push('经济型装修建议重点投入在基础工程,后期可逐步升级软装');
  294. } else if (level === '豪华型' || level === '奢华型') {
  295. suggestions.push('高端装修建议选择知名品牌材料,注重细节工艺和环保性能');
  296. }
  297. // 面积建议
  298. if (area < 60) {
  299. suggestions.push('小户型建议采用开放式设计,合理利用每一寸空间');
  300. } else if (area > 150) {
  301. suggestions.push('大户型建议做好功能分区,可考虑增加储物空间和休闲区域');
  302. }
  303. return suggestions;
  304. }
  305. /**
  306. * 获取装修风格列表
  307. * @returns 风格列表
  308. */
  309. getStyleOptions(): string[] {
  310. return Object.keys(this.styleMultipliers);
  311. }
  312. /**
  313. * 获取装修档次列表
  314. * @returns 档次列表
  315. */
  316. getLevelOptions(): string[] {
  317. return Object.keys(this.levelMultipliers);
  318. }
  319. }