consultation-order-panel.component.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <div class="consultation-order-panel">
  2. <!-- 面板头部 -->
  3. <div class="panel-header">
  4. <h1 class="panel-title">创建咨询订单</h1>
  5. <p class="panel-subtitle">填写客户信息和项目需求</p>
  6. <!-- 紧凑型流程进度卡片 -->
  7. <div class="compact-stage-indicators">
  8. <div class="stage-chain">
  9. <div class="stage-dot" [class]="getStageStatusClass('customerInfo')"
  10. title="客户信息 - {{ getStageStatusText('customerInfo') }}">
  11. <span class="stage-number">1</span>
  12. </div>
  13. <div class="stage-connector" [class]="stageCompletionStatus.customerInfo ? 'completed' : 'pending'"></div>
  14. <div class="stage-dot" [class]="getStageStatusClass('projectRequirements')"
  15. title="项目需求 - {{ getStageStatusText('projectRequirements') }}">
  16. <span class="stage-number">2</span>
  17. </div>
  18. <div class="stage-connector" [class]="stageCompletionStatus.projectRequirements ? 'completed' : 'pending'"></div>
  19. <div class="stage-dot" [class]="getStageStatusClass('teamAssignment')"
  20. title="团队分配 - {{ getStageStatusText('teamAssignment') }}">
  21. <span class="stage-number">3</span>
  22. </div>
  23. <div class="stage-connector" [class]="stageCompletionStatus.teamAssignment ? 'completed' : 'pending'"></div>
  24. <div class="stage-dot" [class]="getStageStatusClass('orderConfirmation')"
  25. title="订单确认 - {{ getStageStatusText('orderConfirmation') }}">
  26. <span class="stage-number">4</span>
  27. </div>
  28. </div>
  29. </div>
  30. <div class="progress-indicator">
  31. <div class="progress-bar">
  32. <div class="progress-fill" [style.width.%]="getProgressPercentage()"></div>
  33. </div>
  34. <span class="progress-text">{{ getProgressPercentage() | number:'1.0-0' }}% 完成</span>
  35. </div>
  36. </div>
  37. <!-- 可滚动内容区域 -->
  38. <div class="panel-content">
  39. <!-- 客户信息栏 -->
  40. <section class="customer-info-section">
  41. <h2 class="section-title">客户信息</h2>
  42. @if (!selectedCustomer) {
  43. <!-- 客户搜索 -->
  44. <div class="search-container">
  45. <input
  46. type="text"
  47. [(ngModel)]="searchKeyword"
  48. (ngModelChange)="searchCustomer()"
  49. placeholder="输入客户姓名或手机号搜索..."
  50. class="search-input"
  51. autocomplete="off"
  52. />
  53. <button class="search-btn" (click)="searchCustomer()">搜索</button>
  54. </div>
  55. <!-- 搜索结果 -->
  56. @if (searchResults.length > 0) {
  57. <div class="search-results">
  58. @for (customer of searchResults; track customer.id) {
  59. <div class="result-item" (click)="selectCustomer(customer)">
  60. <div class="customer-name">{{ customer.name }}</div>
  61. <div class="customer-info">{{ customer.phone }}</div>
  62. </div>
  63. }
  64. </div>
  65. }
  66. } @else {
  67. <!-- 已选择客户 -->
  68. <div class="selected-customer">
  69. <div class="customer-details">
  70. <div class="customer-name">{{ selectedCustomer.name }}</div>
  71. <div class="customer-phone">{{ selectedCustomer.phone }}</div>
  72. </div>
  73. <button class="clear-btn" (click)="clearSelectedCustomer()">重新选择</button>
  74. </div>
  75. }
  76. </section>
  77. <!-- 新客户表单 -->
  78. @if (!selectedCustomer) {
  79. <section class="new-customer-form">
  80. <h3 class="form-title">新客户信息</h3>
  81. <form [formGroup]="customerForm">
  82. <div class="form-row">
  83. <div class="form-group">
  84. <label for="wechat">微信号</label>
  85. <input type="text" id="wechat" formControlName="wechat" placeholder="请输入微信号(选填)">
  86. </div>
  87. <div class="form-group">
  88. <label for="customerType">客户类型</label>
  89. <select id="customerType" formControlName="customerType">
  90. <option value="">请选择客户类型</option>
  91. <option value="新客户">新客户</option>
  92. <option value="老客户">老客户</option>
  93. <option value="转介绍">转介绍</option>
  94. </select>
  95. </div>
  96. </div>
  97. </form>
  98. </section>
  99. }
  100. <!-- 项目需求卡片 -->
  101. <section class="requirements-card">
  102. <div class="card-header" (click)="isRequirementCardExpanded = !isRequirementCardExpanded">
  103. <h3 class="card-title">项目需求</h3>
  104. <span class="toggle-icon" [class.expanded]="isRequirementCardExpanded">▼</span>
  105. </div>
  106. @if (isRequirementCardExpanded) {
  107. <div class="card-content">
  108. <form [formGroup]="requirementForm">
  109. <!-- 基本信息 - 两列布局 -->
  110. <div class="form-row two-columns">
  111. <div class="form-group">
  112. <label for="downPayment">定金金额 <span class="required">*</span></label>
  113. <input type="number" id="downPayment" formControlName="downPayment" placeholder="请输入定金金额">
  114. </div>
  115. <div class="form-group">
  116. <label for="budget">预算范围 <span class="required">*</span></label>
  117. <input type="number" id="budget" formControlName="budget" placeholder="请输入预算金额">
  118. </div>
  119. </div>
  120. <div class="form-row two-columns">
  121. <div class="form-group">
  122. <label for="area">房屋面积 <span class="required">*</span></label>
  123. <input type="number" id="area" formControlName="area" placeholder="请输入房屋面积(平方米)">
  124. </div>
  125. <div class="form-group">
  126. <label for="houseType">房屋类型</label>
  127. <input type="text" id="houseType" formControlName="houseType" placeholder="如:三室两厅">
  128. </div>
  129. </div>
  130. <div class="form-row two-columns">
  131. <div class="form-group">
  132. <label for="smallImageTime">小图时间</label>
  133. <input type="date" id="smallImageTime" formControlName="smallImageTime">
  134. </div>
  135. <div class="form-group">
  136. <label for="largeImageTime">大图时间</label>
  137. <input type="date" id="largeImageTime" formControlName="largeImageTime">
  138. </div>
  139. </div>
  140. <!-- 详细需求 - 单列布局 -->
  141. <div class="form-row single-column">
  142. <div class="form-group">
  143. <label for="spaceRequirements">涉及空间</label>
  144. <textarea
  145. id="spaceRequirements"
  146. formControlName="spaceRequirements"
  147. rows="3"
  148. placeholder="请描述涉及的空间,如:客厅、卧室、厨房等"
  149. ></textarea>
  150. </div>
  151. </div>
  152. <div class="form-row single-column">
  153. <div class="form-group">
  154. <label for="designAngles">设计角度</label>
  155. <textarea
  156. id="designAngles"
  157. formControlName="designAngles"
  158. rows="3"
  159. placeholder="请明确各个空间的展示角度"
  160. ></textarea>
  161. </div>
  162. </div>
  163. <div class="form-row single-column">
  164. <div class="form-group">
  165. <label for="specialAreaHandling">特殊区域处理</label>
  166. <textarea
  167. id="specialAreaHandling"
  168. formControlName="specialAreaHandling"
  169. rows="3"
  170. placeholder="请描述特殊区域的处理要求"
  171. ></textarea>
  172. </div>
  173. </div>
  174. <div class="form-row single-column">
  175. <div class="form-group">
  176. <label for="materialRequirements">材质要求</label>
  177. <textarea
  178. id="materialRequirements"
  179. formControlName="materialRequirements"
  180. rows="3"
  181. placeholder="请描述对材质的具体要求"
  182. ></textarea>
  183. </div>
  184. </div>
  185. <div class="form-row single-column">
  186. <div class="form-group">
  187. <label for="lightingRequirements">灯光要求</label>
  188. <textarea
  189. id="lightingRequirements"
  190. formControlName="lightingRequirements"
  191. rows="3"
  192. placeholder="请描述对灯光的具体要求"
  193. ></textarea>
  194. </div>
  195. </div>
  196. <!-- 偏好标签 -->
  197. <div class="tags-section">
  198. <h4 class="tags-title">偏好标签</h4>
  199. <div class="tags-container">
  200. @for (tag of preferenceTags; track tag) {
  201. <span class="tag">
  202. {{ tag }}
  203. <button type="button" class="remove-tag" (click)="removePreferenceTag(tag)">×</button>
  204. </span>
  205. }
  206. </div>
  207. <div class="tag-input-container">
  208. <input
  209. type="text"
  210. [(ngModel)]="newTag"
  211. placeholder="添加偏好标签"
  212. class="tag-input"
  213. (keyup.enter)="addPreferenceTag(newTag)"
  214. />
  215. <button type="button" class="add-tag-btn" (click)="addPreferenceTag(newTag)">添加</button>
  216. </div>
  217. </div>
  218. </form>
  219. </div>
  220. }
  221. </section>
  222. </div>
  223. <!-- 底部提交区域 -->
  224. <div class="panel-footer">
  225. <button
  226. class="submit-btn"
  227. (click)="submitForm()"
  228. [disabled]="isSubmitting || !isFormValid()"
  229. [class.disabled]="isSubmitting || !isFormValid()"
  230. >
  231. @if (isSubmitting) {
  232. <span>分配团队中...</span>
  233. } @else {
  234. <span>创建订单</span>
  235. }
  236. </button>
  237. <!-- 表单验证提示 -->
  238. @if (!isFormValid()) {
  239. <div class="validation-hint">
  240. <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
  241. <circle cx="12" cy="12" r="10"></circle>
  242. <line x1="12" y1="8" x2="12" y2="12"></line>
  243. <line x1="12" y1="16" x2="12.01" y2="16"></line>
  244. </svg>
  245. 请填写完整的项目信息
  246. </div>
  247. }
  248. </div>
  249. </div>
  250. <!-- 团队分配弹窗 -->
  251. <app-team-assignment-modal
  252. [isVisible]="showTeamAssignmentModal"
  253. (closeModal)="closeTeamAssignmentModal()"
  254. (confirmAssignment)="confirmTeamAssignment($event)">
  255. </app-team-assignment-modal>