# 订单分配阶段组件拆分方案 ## 📦 概述 将订单分配阶段(`StageOrderComponent`)拆分为多个可复用的子组件,提高代码的可维护性、可测试性和可复用性。 --- ## 🎯 拆分目标 1. **模块化**:每个组件负责单一职责 2. **可复用**:组件可在其他地方复用 3. **易维护**:代码结构清晰,易于理解和修改 4. **易测试**:每个组件可独立测试 5. **性能优化**:支持OnPush变更检测策略 --- ## 📂 组件结构 ``` stage-order/ ├── components/ # 子组件目录 │ ├── approval-status-banner/ # 审批状态横幅 │ │ ├── approval-status-banner.component.ts │ │ ├── approval-status-banner.component.html │ │ └── approval-status-banner.component.scss │ ├── leader-approval-bar/ # 组长审批操作条 │ │ ├── leader-approval-bar.component.ts │ │ ├── leader-approval-bar.component.html │ │ └── leader-approval-bar.component.scss │ ├── project-basic-info/ # 项目基本信息 │ │ ├── project-basic-info.component.ts │ │ ├── project-basic-info.component.html │ │ └── project-basic-info.component.scss │ └── order-action-buttons/ # 操作按钮 │ ├── order-action-buttons.component.ts │ ├── order-action-buttons.component.html │ └── order-action-buttons.component.scss ├── stage-order.component.ts # 主组件 ├── stage-order.component.html # 主组件模板 └── stage-order.component.scss # 主组件样式 ``` --- ## 🧩 子组件详解 ### 1. ApprovalStatusBannerComponent(审批状态横幅) **职责**:显示订单审批状态(待审批、已通过、已驳回) **输入属性**: - `status`: ApprovalStatus | null - 审批状态 - `rejectionReason`: string - 驳回原因 **输出事件**: - `resubmit`: void - 重新提交事件 **使用示例**: ```html ``` **特性**: - 3种状态样式(pending/approved/rejected) - 支持重新提交操作 - 响应式设计,移动端优化 - 下滑动画效果 --- ### 2. LeaderApprovalBarComponent(组长审批操作条) **职责**:提供组长审批订单的操作按钮 **输入属性**: - `saving`: boolean - 是否正在保存 **输出事件**: - `approve`: void - 通过审批事件 - `reject`: void - 驳回订单事件 **使用示例**: ```html ``` **特性**: - 渐变背景按钮 - 波纹点击效果 - 禁用状态处理 - 移动端纵向排列 --- ### 3. ProjectBasicInfoComponent(项目基本信息) **职责**:可折叠的项目基本信息表单 **输入属性**: - `projectInfo`: ProjectInfo - 项目信息对象 - `expanded`: boolean - 是否展开 - `canEdit`: boolean - 是否可编辑 **输出事件**: - `expandedChange`: boolean - 展开状态变化 - `projectInfoChange`: ProjectInfo - 项目信息变化 - `projectTypeChange`: string - 项目类型变化 **接口定义**: ```typescript export interface ProjectInfo { title: string; projectType: string; renderType: string; demoday: Date | null; deadline: Date | null; description: string; priceLevel: string; spaceType: string; } ``` **使用示例**: ```html ``` **特性**: - 可折叠交互 - 双向数据绑定 - 日期选择器集成 - 条件渲染(渲染类型仅家装显示) - 完整的表单验证支持 --- ### 4. OrderActionButtonsComponent(操作按钮) **职责**:提供保存草稿和确认订单操作 **输入属性**: - `canEdit`: boolean - 是否可编辑 - `saving`: boolean - 是否正在保存 - `submittedPending`: boolean - 是否已提交待审批 - `approvalStatus`: string | null - 审批状态 **输出事件**: - `saveDraft`: void - 保存草稿事件 - `submit`: void - 提交订单事件 **使用示例**: ```html ``` **特性**: - 自动禁用逻辑 - 渐变样式按钮 - 移动端优化布局 - 图标+文字组合 --- ## 🔄 主组件更新 ### 修改后的HTML结构 ```html
@if (project) { } @if (getApprovalStatus() === 'pending' && isTeamLeader && !isFromCustomerService) { }
``` ### TypeScript导入更新 ```typescript import { ApprovalStatusBannerComponent } from './components/approval-status-banner/approval-status-banner.component'; import { LeaderApprovalBarComponent } from './components/leader-approval-bar/leader-approval-bar.component'; import { ProjectBasicInfoComponent } from './components/project-basic-info/project-basic-info.component'; import { OrderActionButtonsComponent } from './components/order-action-buttons/order-action-buttons.component'; @Component({ selector: 'app-stage-order', standalone: true, imports: [ CommonModule, FormsModule, QuotationEditorComponent, TeamAssignComponent, CustomDatePickerComponent, ApprovalStatusBannerComponent, // 新增 LeaderApprovalBarComponent, // 新增 ProjectBasicInfoComponent, // 新增 OrderActionButtonsComponent // 新增 ], ... }) ``` --- ## 📈 优势对比 ### Before(拆分前) **单一大组件**: - ❌ HTML文件230行,难以阅读 - ❌ 所有逻辑集中在一个组件 - ❌ 难以复用 - ❌ 难以测试 - ❌ 修改影响面广 ### After(拆分后) **模块化小组件**: - ✅ 每个组件职责单一明确 - ✅ HTML结构清晰,易于理解 - ✅ 组件可独立复用 - ✅ 易于单元测试 - ✅ 修改影响范围小 - ✅ 支持OnPush策略,性能更好 --- ## 🎨 样式管理 ### 样式隔离策略 每个子组件都有独立的样式文件,避免样式冲突: ``` approval-status-banner.component.scss # 横幅样式 leader-approval-bar.component.scss # 审批栏样式 project-basic-info.component.scss # 表单样式 order-action-buttons.component.scss # 按钮样式 stage-order.component.scss # 主组件布局样式 ``` ### 共享样式 公共样式可以提取到: - 全局样式文件(styles.scss) - 共享SCSS变量文件 - 主题配置文件 --- ## 🧪 测试建议 ### 单元测试 每个子组件都可以独立测试: ```typescript // approval-status-banner.component.spec.ts describe('ApprovalStatusBannerComponent', () => { it('should display pending status', () => { component.status = 'pending'; fixture.detectChanges(); expect(compiled.querySelector('.status-icon').textContent).toBe('⏳'); }); it('should emit resubmit event', () => { spyOn(component.resubmit, 'emit'); component.onResubmit(); expect(component.resubmit.emit).toHaveBeenCalled(); }); }); ``` ### 集成测试 测试主组件与子组件的交互: ```typescript // stage-order.component.spec.ts describe('StageOrderComponent', () => { it('should pass approval status to banner component', () => { const banner = fixture.debugElement.query(By.directive(ApprovalStatusBannerComponent)); expect(banner.componentInstance.status).toBe('pending'); }); }); ``` --- ## 📱 响应式设计 所有子组件都实现了移动端优化: ### 断点策略 ```scss // 移动端优化 (≤480px) @media (max-width: 480px) { // 横幅纵向布局,居中显示 .approval-status-banner { flex-direction: column; text-align: center; } // 审批按钮纵向排列,占满宽度 .leader-approval-bar { .approval-buttons-container { flex-direction: column; button { width: 100%; } } } // 表单输入框增大触摸区域 .form-input { min-height: 44px; padding: 12px; } } ``` --- ## 🚀 迁移步骤 ### 1. 创建子组件 ✅ 已创建所有子组件文件 ### 2. 更新主组件 ```typescript // stage-order.component.ts // 1. 导入子组件 import { ApprovalStatusBannerComponent } from './components/approval-status-banner/approval-status-banner.component'; // ... 其他导入 // 2. 添加到imports数组 @Component({ imports: [ // ... 现有导入 ApprovalStatusBannerComponent, LeaderApprovalBarComponent, ProjectBasicInfoComponent, OrderActionButtonsComponent ] }) // 3. 添加事件处理方法(如果需要) onProjectInfoChange(info: ProjectInfo): void { this.projectInfo = info; // 触发变更检测或其他操作 } ``` ### 3. 更新主组件HTML 将原有的HTML块替换为子组件标签 ### 4. 清理主组件样式 将已移到子组件的样式从主组件SCSS中删除 ### 5. 测试验证 - [ ] 审批状态显示正常 - [ ] 审批按钮点击正常 - [ ] 项目信息表单交互正常 - [ ] 操作按钮功能正常 - [ ] 移动端布局正常 --- ## 🔧 维护建议 ### 1. 组件职责 - 每个组件只负责自己的UI和交互 - 业务逻辑保留在主组件 - 子组件通过事件与主组件通信 ### 2. 数据流 ``` 主组件 (StageOrderComponent) ↓ @Input 子组件 (ApprovalStatusBannerComponent) ↓ @Output 主组件 (StageOrderComponent) ``` ### 3. 性能优化 - 所有子组件使用OnPush策略 - 使用Immutable数据更新 - 避免在模板中使用复杂计算 ### 4. 代码复用 这些组件可以在其他地方复用: - 审批状态横幅 → 其他需要审批的页面 - 操作按钮 → 其他表单页面 - 项目信息表单 → 项目编辑页面 --- ## 📊 代码量对比 ### Before(拆分前) | 文件 | 行数 | 说明 | |------|------|------| | stage-order.component.html | 230行 | 所有HTML在一个文件 | | stage-order.component.scss | 3024行 | 所有样式在一个文件 | | stage-order.component.ts | 2170行 | 所有逻辑在一个文件 | | **总计** | **5424行** | | ### After(拆分后) | 文件 | 行数 | 说明 | |------|------|------| | **主组件** | | stage-order.component.html | ~80行 | 组件编排 | | stage-order.component.scss | ~500行 | 布局样式 | | stage-order.component.ts | ~1500行 | 主要逻辑 | | **子组件** | | approval-status-banner | ~200行 | 3个文件 | | leader-approval-bar | ~150行 | 3个文件 | | project-basic-info | ~400行 | 3个文件 | | order-action-buttons | ~150行 | 3个文件 | | **总计** | **~3000行** | 13个文件 | **优势**: - ✅ 代码行数减少44% - ✅ 文件组织更清晰 - ✅ 易于定位和修改 - ✅ 支持并行开发 --- ## ✅ 完成清单 - [x] 创建ApprovalStatusBannerComponent - [x] 创建LeaderApprovalBarComponent - [x] 创建ProjectBasicInfoComponent - [x] 创建OrderActionButtonsComponent - [ ] 更新主组件导入 - [ ] 更新主组件HTML - [ ] 更新主组件样式 - [ ] 添加单元测试 - [ ] 测试移动端布局 - [ ] 文档更新 --- ## 🎯 下一步 1. **更新主组件**:导入并使用新创建的子组件 2. **清理代码**:删除已移到子组件的代码 3. **测试验证**:确保功能正常 4. **性能测试**:验证OnPush策略效果 5. **代码审查**:团队review代码质量 --- ## 📚 参考资料 - [Angular组件交互](https://angular.io/guide/component-interaction) - [变更检测策略](https://angular.io/api/core/ChangeDetectionStrategy) - [响应式设计最佳实践](https://web.dev/responsive-web-design-basics/) - [组件样式隔离](https://angular.io/guide/component-styles) --- **创建时间**:2024-12-09 **状态**:✅ 子组件创建完成,待集成到主组件