Переглянути джерело

feat(订单流程): 实现咨询订单提交及需求沟通阶段跳转功能

- 在项目详情页添加订单数据存储和阶段跳转逻辑
- 重构咨询订单面板组件,优化表单字段和样式
- 添加订单创建阶段的需求信息展示区域
- 改进提交按钮样式和交互状态
0235711 1 день тому
батько
коміт
c76a0f15e3

+ 112 - 45
src/app/pages/designer/project-detail/project-detail.html

@@ -159,8 +159,19 @@
               <h2>客户信息</h2>
               @if (project) {
                 <div class="info-grid">
-                  <div class="info-item key-info"><label>客户姓名</label><span>{{ project.customerName }}</span></div>
-                  <div class="info-item key-info"><label>项目负责人</label><span>{{ project.assigneeName }}</span></div>
+                  <!-- 显示订单创建时填写的客户信息,如果有的话 -->
+                  @if (orderCreationData?.customerInfo) {
+                    <div class="info-item key-info"><label>客户姓名</label><span>{{ orderCreationData.customerInfo.name }}</span></div>
+                    <div class="info-item key-info"><label>手机号码</label><span>{{ orderCreationData.customerInfo.phone }}</span></div>
+                    @if (orderCreationData.customerInfo.wechat) {
+                      <div class="info-item"><label>微信号</label><span>{{ orderCreationData.customerInfo.wechat }}</span></div>
+                    }
+                    <div class="info-item"><label>客户类型</label><span>{{ orderCreationData.customerInfo.customerType }}</span></div>
+                  } @else {
+                    <!-- 默认显示项目信息 -->
+                    <div class="info-item key-info"><label>客户姓名</label><span>{{ project.customerName }}</span></div>
+                    <div class="info-item key-info"><label>项目负责人</label><span>{{ project.assigneeName }}</span></div>
+                  }
                   <div class="info-item"><label>项目创建</label><span>{{ formatDate(project.createdAt) }}</span></div>
                   <div class="info-item"><label>截止日期</label><span>{{ formatDate(project.deadline) }}</span></div>
                 </div>
@@ -185,55 +196,111 @@
                     
                     <!-- 新增:需求关键信息同步区域 -->
                     <div class="requirement-sync-info">
-                      <h4>确认需求关键信息</h4>
-                      <div class="key-info-grid">
-                        @if (requirementKeyInfo.colorAtmosphere.description) {
-                          <div class="info-item">
-                            <span class="info-label">色彩氛围</span>
-                            <span class="info-value">{{ requirementKeyInfo.colorAtmosphere.description }}</span>
-                            <div class="color-preview" [style.background-color]="requirementKeyInfo.colorAtmosphere.mainColor"></div>
-                          </div>
-                        }
-                        
-                        @if (requirementKeyInfo.spaceStructure.aspectRatio > 0) {
-                          <div class="info-item">
-                            <span class="info-label">空间结构</span>
-                            <span class="info-value">比例 {{ requirementKeyInfo.spaceStructure.aspectRatio.toFixed(1) }}</span>
+                      <h4>项目需求信息</h4>
+                      
+                      <!-- 显示订单创建时填写的需求信息 -->
+                      @if (orderCreationData?.requirementInfo) {
+                        <div class="order-requirement-info">
+                          <h5>订单创建阶段需求</h5>
+                          <div class="key-info-grid">
+                            @if (orderCreationData.requirementInfo.decorationType) {
+                              <div class="info-item">
+                                <span class="info-label">装修类型</span>
+                                <span class="info-value">{{ orderCreationData.requirementInfo.decorationType }}</span>
+                              </div>
+                            }
+                            @if (orderCreationData.requirementInfo.downPayment) {
+                              <div class="info-item">
+                                <span class="info-label">首付款</span>
+                                <span class="info-value">¥{{ orderCreationData.requirementInfo.downPayment }}</span>
+                              </div>
+                            }
+                            @if (orderCreationData.requirementInfo.firstDraftDate) {
+                              <div class="info-item">
+                                <span class="info-label">首稿时间</span>
+                                <span class="info-value">{{ orderCreationData.requirementInfo.firstDraftDate }}</span>
+                              </div>
+                            }
+                            @if (orderCreationData.requirementInfo.style) {
+                              <div class="info-item">
+                                <span class="info-label">装修风格</span>
+                                <span class="info-value">{{ orderCreationData.requirementInfo.style }}</span>
+                              </div>
+                            }
+                            @if (orderCreationData.requirementInfo.spaceRequirements) {
+                              <div class="info-item">
+                                <span class="info-label">涉及空间</span>
+                                <span class="info-value">{{ orderCreationData.requirementInfo.spaceRequirements }}</span>
+                              </div>
+                            }
                           </div>
-                        }
-                        
-                        @if (requirementKeyInfo.materialWeights.woodRatio > 0 || requirementKeyInfo.materialWeights.fabricRatio > 0) {
-                          <div class="info-item">
-                            <span class="info-label">材质权重</span>
-                            <div class="material-weights">
-                              @if (requirementKeyInfo.materialWeights.woodRatio > 0) {
-                                <span class="weight-item">木质 {{ requirementKeyInfo.materialWeights.woodRatio }}%</span>
-                              }
-                              @if (requirementKeyInfo.materialWeights.fabricRatio > 0) {
-                                <span class="weight-item">布艺 {{ requirementKeyInfo.materialWeights.fabricRatio }}%</span>
-                              }
-                              @if (requirementKeyInfo.materialWeights.metalRatio > 0) {
-                                <span class="weight-item">金属 {{ requirementKeyInfo.materialWeights.metalRatio }}%</span>
-                              }
+                          
+                          <!-- 显示偏好标签 -->
+                          @if (orderCreationData.preferenceTags && orderCreationData.preferenceTags.length > 0) {
+                            <div class="preference-tags">
+                              <span class="info-label">偏好标签:</span>
+                              <div class="tags">
+                                @for (tag of orderCreationData.preferenceTags; track tag) {
+                                  <span class="tag">{{ tag }}</span>
+                                }
+                              </div>
                             </div>
-                          </div>
-                        }
+                          }
+                        </div>
+                      }
+                      
+                      <!-- 确认需求阶段的关键信息 -->
+                      <div class="confirmed-requirement-info">
+                        <h5>确认需求关键信息</h5>
+                        <div class="key-info-grid">
+                          @if (requirementKeyInfo.colorAtmosphere.description) {
+                            <div class="info-item">
+                              <span class="info-label">色彩氛围</span>
+                              <span class="info-value">{{ requirementKeyInfo.colorAtmosphere.description }}</span>
+                              <div class="color-preview" [style.background-color]="requirementKeyInfo.colorAtmosphere.mainColor"></div>
+                            </div>
+                          }
+                          
+                          @if (requirementKeyInfo.spaceStructure.aspectRatio > 0) {
+                            <div class="info-item">
+                              <span class="info-label">空间结构</span>
+                              <span class="info-value">比例 {{ requirementKeyInfo.spaceStructure.aspectRatio.toFixed(1) }}</span>
+                            </div>
+                          }
+                          
+                          @if (requirementKeyInfo.materialWeights.woodRatio > 0 || requirementKeyInfo.materialWeights.fabricRatio > 0) {
+                            <div class="info-item">
+                              <span class="info-label">材质权重</span>
+                              <div class="material-weights">
+                                @if (requirementKeyInfo.materialWeights.woodRatio > 0) {
+                                  <span class="weight-item">木质 {{ requirementKeyInfo.materialWeights.woodRatio }}%</span>
+                                }
+                                @if (requirementKeyInfo.materialWeights.fabricRatio > 0) {
+                                  <span class="weight-item">布艺 {{ requirementKeyInfo.materialWeights.fabricRatio }}%</span>
+                                }
+                                @if (requirementKeyInfo.materialWeights.metalRatio > 0) {
+                                  <span class="weight-item">金属 {{ requirementKeyInfo.materialWeights.metalRatio }}%</span>
+                                }
+                              </div>
+                            </div>
+                          }
+                          
+                          @if (requirementKeyInfo.presetAtmosphere.name) {
+                            <div class="info-item">
+                              <span class="info-label">预设氛围</span>
+                              <span class="info-value">{{ requirementKeyInfo.presetAtmosphere.name }}</span>
+                              <span class="color-temp">{{ requirementKeyInfo.presetAtmosphere.colorTemp }}</span>
+                            </div>
+                          }
+                        </div>
                         
-                        @if (requirementKeyInfo.presetAtmosphere.name) {
-                          <div class="info-item">
-                            <span class="info-label">预设氛围</span>
-                            <span class="info-value">{{ requirementKeyInfo.presetAtmosphere.name }}</span>
-                            <span class="color-temp">{{ requirementKeyInfo.presetAtmosphere.colorTemp }}</span>
+                        @if (getRequirementSummary().length === 0 && !orderCreationData?.requirementInfo) {
+                          <div class="sync-placeholder">
+                            <span class="placeholder-text">暂无同步的需求信息</span>
+                            <button class="sync-btn" (click)="syncRequirementKeyInfo({})">手动同步</button>
                           </div>
                         }
                       </div>
-                      
-                      @if (getRequirementSummary().length === 0) {
-                        <div class="sync-placeholder">
-                          <span class="placeholder-text">暂无同步的需求信息</span>
-                          <button class="sync-btn" (click)="syncRequirementKeyInfo({})">手动同步</button>
-                        </div>
-                      }
                     </div>
                   </div>
                 </div>

+ 54 - 1
src/app/pages/designer/project-detail/project-detail.scss

@@ -225,7 +225,7 @@
         font-size: 14px;
         font-weight: 600;
         color: #1d1d1f;
-        margin: 0 0 12px 0;
+        margin: 0 0 16px 0;
         display: flex;
         align-items: center;
         gap: 6px;
@@ -239,6 +239,59 @@
         }
       }
 
+      h5 {
+        font-size: 13px;
+        font-weight: 600;
+        color: #1d1d1f;
+        margin: 0 0 12px 0;
+        padding-bottom: 6px;
+        border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+      }
+
+      .order-requirement-info {
+        margin-bottom: 20px;
+        padding: 12px;
+        background: rgba(52, 199, 89, 0.02);
+        border: 1px solid rgba(52, 199, 89, 0.1);
+        border-radius: 6px;
+
+        .preference-tags {
+          margin-top: 12px;
+          padding-top: 12px;
+          border-top: 1px solid rgba(0, 0, 0, 0.06);
+
+          .info-label {
+            font-weight: 500;
+            color: #666;
+            margin-bottom: 6px;
+            display: block;
+          }
+
+          .tags {
+            display: flex;
+            flex-wrap: wrap;
+            gap: 6px;
+
+            .tag {
+              font-size: 11px;
+              background: rgba(52, 199, 89, 0.1);
+              color: #34c759;
+              padding: 4px 8px;
+              border-radius: 12px;
+              font-weight: 500;
+              border: 1px solid rgba(52, 199, 89, 0.2);
+            }
+          }
+        }
+      }
+
+      .confirmed-requirement-info {
+        padding: 12px;
+        background: rgba(255, 149, 0, 0.02);
+        border: 1px solid rgba(255, 149, 0, 0.1);
+        border-radius: 6px;
+      }
+
       .key-info-grid {
         display: grid;
         gap: 12px;

+ 21 - 2
src/app/pages/designer/project-detail/project-detail.ts

@@ -1727,9 +1727,28 @@ export class ProjectDetail implements OnInit, OnDestroy {
   }
 
   // 处理咨询订单表单提交
+  // 存储订单创建时的客户信息和需求信息
+  orderCreationData: any = null;
+
   onConsultationOrderSubmit(formData: any): void {
     console.log('咨询订单表单提交:', formData);
-    // 这里可以添加处理表单提交的逻辑
-    // 例如:保存订单信息、更新项目状态等
+    
+    // 保存订单创建数据
+    this.orderCreationData = formData;
+    
+    // 更新项目阶段到下一个阶段(需求沟通)
+    this.updateProjectStage('需求沟通');
+    
+    // 展开下一个阶段
+    this.expandedStages['需求沟通'] = true;
+    this.expandedStages['订单创建'] = false;
+    
+    // 滚动到下一个阶段
+    setTimeout(() => {
+      this.scrollToStage('需求沟通');
+    }, 100);
+    
+    // 显示成功提示
+    console.log('订单创建成功,已跳转到需求沟通阶段');
   }
 }

+ 35 - 16
src/app/shared/components/consultation-order-panel/consultation-order-panel.component.html

@@ -55,11 +55,11 @@
         <form [formGroup]="customerForm">
           <div class="form-row">
             <div class="form-group">
-              <label for="name">客户姓名 *</label>
+              <label for="name">客户姓名 <span class="required">*</span></label>
               <input type="text" id="name" formControlName="name" placeholder="请输入客户姓名">
             </div>
             <div class="form-group">
-              <label for="phone">手机号码 *</label>
+              <label for="phone">手机号码 <span class="required">*</span></label>
               <input type="tel" id="phone" formControlName="phone" placeholder="请输入手机号码">
             </div>
           </div>
@@ -95,24 +95,44 @@
             <!-- 基本信息 -->
             <div class="form-row">
               <div class="form-group">
-                <label for="decorationType">装修类型 *</label>
+                <label for="decorationType">装修类型 <span class="required">*</span></label>
                 <select id="decorationType" formControlName="decorationType">
                   <option value="">请选择装修类型</option>
-                  <option value="家装">家装</option>
-                  <option value="工装">工装</option>
+                  <option value="全包">全包</option>
+                  <option value="半包">半包</option>
+                  <option value="清包">清包</option>
+                  <option value="软装">软装</option>
                 </select>
               </div>
               <div class="form-group">
-                <label for="downPayment">首付款 *</label>
-                <input type="number" id="downPayment" formControlName="downPayment" placeholder="请输入首付款金额">
+                <label for="downPayment">定金金额 <span class="required">*</span></label>
+                <input type="number" id="downPayment" formControlName="downPayment" placeholder="请输入定金金额">
               </div>
             </div>
-            
+
             <div class="form-row">
               <div class="form-group">
-                <label for="firstDraftDate">首稿时间 *</label>
+                <label for="firstDraftDate">初稿时间 <span class="required">*</span></label>
                 <input type="date" id="firstDraftDate" formControlName="firstDraftDate">
               </div>
+              <div class="form-group">
+                <label for="budget">预算范围 <span class="required">*</span></label>
+                <input type="text" id="budget" formControlName="budget" placeholder="请输入预算范围">
+              </div>
+            </div>
+
+            <div class="form-row">
+              <div class="form-group">
+                <label for="area">房屋面积 <span class="required">*</span></label>
+                <input type="number" id="area" formControlName="area" placeholder="请输入房屋面积(平方米)">
+              </div>
+              <div class="form-group">
+                <label for="houseType">房屋类型</label>
+                <input type="text" id="houseType" formControlName="houseType" placeholder="如:三室两厅">
+              </div>
+            </div>
+
+            <div class="form-row">
               <div class="form-group">
                 <label for="style">装修风格</label>
                 <select id="style" formControlName="style">
@@ -215,15 +235,14 @@
 
   <!-- 底部提交区域 -->
   <div class="panel-footer">
-    <button 
-      class="submit-btn" 
-      (click)="submitForm()"
-      [disabled]="isSubmitting || !customerForm.valid || !requirementForm.valid"
-    >
+    <button type="submit" 
+            class="submit-btn" 
+            [disabled]="!customerForm.valid || !requirementForm.valid || isSubmitting"
+            (click)="submitForm()">
       @if (isSubmitting) {
-        提交中...
+        <span>创建中...</span>
       } @else {
-        创建项目
+        <span>创建订单</span>
       }
     </button>
   </div>

+ 17 - 13
src/app/shared/components/consultation-order-panel/consultation-order-panel.component.scss

@@ -379,6 +379,11 @@ $ios-spacing-xl: 32px;
             color: $ios-text-primary;
           }
 
+          .required {
+            color: #ff4444;
+            font-weight: bold;
+          }
+
           input, select, textarea {
             width: 100%;
             padding: 12px $ios-spacing-md;
@@ -519,29 +524,28 @@ $ios-spacing-xl: 32px;
 
     .submit-btn {
       width: 100%;
-      padding: $ios-spacing-md;
-      background: linear-gradient(135deg, $ios-primary 0%, $ios-primary-dark 100%);
-      color: $ios-background;
+      padding: 12px 24px;
+      background: #007bff;
+      color: white;
       border: none;
-      border-radius: $ios-radius;
+      border-radius: 6px;
       font-size: 16px;
-      font-weight: 600;
+      font-weight: 500;
       cursor: pointer;
-      transition: $ios-transition;
-      box-shadow: $ios-shadow-sm;
+      transition: all 0.3s ease;
 
-      &:hover {
-        transform: translateY(-2px);
-        box-shadow: $ios-shadow-md;
+      &:hover:not(:disabled) {
+        background: #0056b3;
+        transform: translateY(-1px);
+        box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);
       }
 
-      &:active {
+      &:active:not(:disabled) {
         transform: translateY(0);
-        box-shadow: $ios-shadow-sm;
       }
 
       &:disabled {
-        background: $ios-text-tertiary;
+        background: #ccc;
         cursor: not-allowed;
         transform: none;
         box-shadow: none;

+ 2 - 2
src/app/shared/components/consultation-order-panel/consultation-order-panel.component.ts

@@ -33,7 +33,7 @@ interface Customer {
   styleUrls: ['./consultation-order-panel.component.scss']
 })
 export class ConsultationOrderPanelComponent {
-  @Output() orderCreated = new EventEmitter<any>();
+  @Output() formSubmit = new EventEmitter<any>();
 
   // 搜索客户关键词
   searchKeyword = '';
@@ -192,7 +192,7 @@ export class ConsultationOrderPanelComponent {
       // 模拟提交请求
       setTimeout(() => {
         this.isSubmitting = false;
-        this.orderCreated.emit(formData);
+        this.formSubmit.emit(formData);
         
         // 重置表单
         this.customerForm.reset({