# 订单分配阶段组件拆分方案
## 📦 概述
将订单分配阶段(`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
**状态**:✅ 子组件创建完成,待集成到主组件