345 lines
8.9 KiB
Markdown
345 lines
8.9 KiB
Markdown
# Design Document
|
||
|
||
## Overview
|
||
|
||
本设计文档描述了结算页面(应结账款)UI优化的技术实现方案。优化目标是提升视觉层次、改善信息密度、增强交互反馈,从而提供更好的用户体验。
|
||
|
||
当前页面基于 Vue 3 + TypeScript + uni-app 框架开发,使用 SCSS 进行样式管理。优化将保持现有架构不变,主要通过调整样式、优化组件结构和改进视觉设计来实现。
|
||
|
||
## Architecture
|
||
|
||
### 组件层次结构
|
||
|
||
```
|
||
settlement.vue (主页面)
|
||
├── DueAlert (到期提醒区域)
|
||
│ └── DueItem[] (到期项列表)
|
||
├── TabNavigation (标签导航)
|
||
│ └── TabItem[] (标签项)
|
||
├── MerchantGroup[] (商户分组)
|
||
│ ├── MerchantHeader (商户头部)
|
||
│ ├── BatchActionButton (批量操作按钮)
|
||
│ └── OrderList (订单列表)
|
||
│ └── OrderItem[] (订单项)
|
||
│ ├── OrderHeader (订单头部)
|
||
│ ├── OrderContent (订单内容)
|
||
│ └── OrderFooter (订单操作)
|
||
└── EmptyState (空状态)
|
||
```
|
||
|
||
### 样式架构
|
||
|
||
采用 BEM 命名规范和模块化 SCSS:
|
||
- 使用语义化的颜色变量
|
||
- 统一的间距系统(基于 4rpx 倍数)
|
||
- 响应式字体大小
|
||
- 可复用的混入(mixin)
|
||
|
||
## Components and Interfaces
|
||
|
||
### 1. DueAlert Component
|
||
|
||
**职责**: 显示即将到期的账款提醒
|
||
|
||
**Props**: 无(从 store 获取数据)
|
||
|
||
**数据源**: `financeStore.dueOrders`
|
||
|
||
**视觉特性**:
|
||
- 琥珀色背景 (#fffbe6)
|
||
- 警告图标 + 标题
|
||
- 横向滚动列表
|
||
- 卡片式到期项
|
||
|
||
### 2. TabNavigation Component
|
||
|
||
**职责**: 提供未结/已结状态切换
|
||
|
||
**Props**: 无
|
||
|
||
**状态**: `currentTab` (0: 未结, 1: 已结)
|
||
|
||
**视觉特性**:
|
||
- 固定在顶部
|
||
- 活动标签蓝色下划线
|
||
- 平滑过渡动画
|
||
|
||
### 3. MerchantGroup Component
|
||
|
||
**职责**: 按商户聚合显示账款信息
|
||
|
||
**数据结构**:
|
||
```typescript
|
||
interface MerchantGroup {
|
||
merchantId: string
|
||
merchantName: string
|
||
settlements: Settlement[]
|
||
totalAmount: number
|
||
hasOverdue: boolean
|
||
}
|
||
```
|
||
|
||
**视觉特性**:
|
||
- 圆角卡片 (16rpx)
|
||
- 渐变头部背景
|
||
- 逾期徽章
|
||
- 突出显示总金额
|
||
|
||
### 4. OrderItem Component
|
||
|
||
**职责**: 显示单个订单的结算信息
|
||
|
||
**数据结构**:
|
||
```typescript
|
||
interface Settlement {
|
||
id: string
|
||
orderNo: string
|
||
merchantId: string
|
||
merchantName: string
|
||
amount: number
|
||
dueDate: string
|
||
settlementDate?: string
|
||
status: SettlementStatus
|
||
}
|
||
```
|
||
|
||
**视觉特性**:
|
||
- 清晰的信息层次
|
||
- 状态徽章(颜色编码)
|
||
- 金额突出显示
|
||
- 操作按钮(未结状态)
|
||
|
||
## Data Models
|
||
|
||
### SettlementStatus Enum
|
||
|
||
```typescript
|
||
enum SettlementStatus {
|
||
UNSETTLED = 'unsettled', // 未结
|
||
SETTLED = 'settled', // 已结
|
||
OVERDUE = 'overdue' // 已逾期
|
||
}
|
||
```
|
||
|
||
### Settlement Interface
|
||
|
||
```typescript
|
||
interface Settlement {
|
||
id: string
|
||
orderNo: string
|
||
merchantId: string
|
||
merchantName: string
|
||
amount: number
|
||
dueDate: string
|
||
settlementDate?: string
|
||
status: SettlementStatus
|
||
}
|
||
```
|
||
|
||
### DueOrder Interface
|
||
|
||
```typescript
|
||
interface DueOrder {
|
||
id: string
|
||
dueDate: string
|
||
amount: number
|
||
}
|
||
```
|
||
|
||
## Correctness Properties
|
||
|
||
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
|
||
|
||
### Property 1: Due Alert Visibility Consistency
|
||
|
||
*For any* state of the due orders list, when the list is empty, the Due Alert component should not be rendered in the DOM
|
||
**Validates: Requirements 1.4**
|
||
|
||
### Property 2: Merchant Grouping Completeness
|
||
|
||
*For any* settlement list, all settlements should be grouped by merchantId with no settlements left ungrouped or duplicated across groups
|
||
**Validates: Requirements 2.1**
|
||
|
||
### Property 3: Status Badge Color Mapping
|
||
|
||
*For any* settlement status value, the rendered status badge should use the correct color scheme (green for settled, amber for unsettled, red for overdue)
|
||
**Validates: Requirements 3.3**
|
||
|
||
### Property 4: Amount Display Formatting
|
||
|
||
*For any* numeric amount value, when displayed in the UI, it should be formatted with exactly 2 decimal places and prefixed with the ¥ symbol
|
||
**Validates: Requirements 3.4**
|
||
|
||
### Property 5: Tab State Synchronization
|
||
|
||
*For any* tab selection change, the active tab indicator should update and the corresponding settlement data should be loaded matching the selected status
|
||
**Validates: Requirements 5.4**
|
||
|
||
### Property 6: Button Interaction Feedback
|
||
|
||
*For any* button press event, the button should apply 0.8 opacity during the active state to provide visual feedback
|
||
**Validates: Requirements 4.3**
|
||
|
||
### Property 7: Overdue Badge Display Logic
|
||
|
||
*For any* merchant group, the overdue badge should be displayed if and only if at least one settlement in that group has status OVERDUE
|
||
**Validates: Requirements 2.3**
|
||
|
||
### Property 8: Empty State Rendering
|
||
|
||
*For any* state where the grouped merchant list is empty, the empty state component should be displayed with centered alignment and appropriate messaging
|
||
**Validates: Requirements 6.1, 6.2, 6.3, 6.4**
|
||
|
||
### Property 9: Spacing Consistency
|
||
|
||
*For any* rendered card or container element, the padding and margin values should follow the 4rpx-based spacing system (20rpx, 24rpx, etc.)
|
||
**Validates: Requirements 7.1, 7.2, 7.3**
|
||
|
||
### Property 10: Color Semantic Consistency
|
||
|
||
*For any* UI element representing a specific semantic meaning (primary action, amount, success, warning, danger), the color used should match the defined color palette
|
||
**Validates: Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6**
|
||
|
||
## Error Handling
|
||
|
||
### 数据加载错误
|
||
|
||
- 使用 uni.showToast 显示错误提示
|
||
- 保持当前状态,允许用户重试
|
||
- 下拉刷新作为恢复机制
|
||
|
||
### 消账提交错误
|
||
|
||
- 显示具体错误信息
|
||
- 保持弹窗打开,允许用户修改后重试
|
||
- 使用 loading 状态防止重复提交
|
||
|
||
### 空数据处理
|
||
|
||
- 显示友好的空状态页面
|
||
- 提供明确的提示信息
|
||
- 不显示错误,因为空数据是正常状态
|
||
|
||
## Testing Strategy
|
||
|
||
### Unit Testing
|
||
|
||
本项目将使用 **Vitest** 作为单元测试框架,配合 **@vue/test-utils** 进行 Vue 组件测试。
|
||
|
||
**测试范围**:
|
||
|
||
1. **计算属性测试**
|
||
- `groupedByMerchant`: 验证商户分组逻辑正确性
|
||
- `currentWriteOffAmount`: 验证单个/批量消账金额计算
|
||
|
||
2. **方法测试**
|
||
- `getStatusText()`: 验证状态文本映射
|
||
- `getStatusClass()`: 验证状态样式类映射
|
||
- `handleTabChange()`: 验证标签切换逻辑
|
||
|
||
3. **边界情况**
|
||
- 空数据列表
|
||
- 单个商户多个订单
|
||
- 全部逾期订单
|
||
|
||
### Property-Based Testing
|
||
|
||
本项目将使用 **fast-check** 作为属性测试库,验证通用正确性属性。
|
||
|
||
**配置要求**:
|
||
- 每个属性测试至少运行 100 次迭代
|
||
- 使用明确的注释标记关联的设计文档属性
|
||
|
||
**测试属性**:
|
||
|
||
每个属性测试必须使用以下格式的注释标记:
|
||
```typescript
|
||
// **Feature: settlement-ui-optimization, Property {number}: {property_text}**
|
||
```
|
||
|
||
**属性测试列表**:
|
||
|
||
1. **Property 1**: Due Alert Visibility Consistency
|
||
2. **Property 2**: Merchant Grouping Completeness
|
||
3. **Property 3**: Status Badge Color Mapping
|
||
4. **Property 4**: Amount Display Formatting
|
||
5. **Property 5**: Tab State Synchronization
|
||
6. **Property 6**: Button Interaction Feedback
|
||
7. **Property 7**: Overdue Badge Display Logic
|
||
8. **Property 8**: Empty State Rendering
|
||
9. **Property 9**: Spacing Consistency
|
||
10. **Property 10**: Color Semantic Consistency
|
||
|
||
### 测试工具和依赖
|
||
|
||
```json
|
||
{
|
||
"devDependencies": {
|
||
"vitest": "^1.0.0",
|
||
"@vue/test-utils": "^2.4.0",
|
||
"fast-check": "^3.15.0",
|
||
"@vitest/ui": "^1.0.0"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 测试命令
|
||
|
||
```bash
|
||
# 运行所有测试
|
||
pnpm test
|
||
|
||
# 运行单元测试
|
||
pnpm test:unit
|
||
|
||
# 运行属性测试
|
||
pnpm test:property
|
||
|
||
# 测试覆盖率
|
||
pnpm test:coverage
|
||
```
|
||
|
||
## Implementation Notes
|
||
|
||
### 样式优化重点
|
||
|
||
1. **颜色系统**
|
||
- 主色:#1890ff (蓝色)
|
||
- 金额:#ff4d4f (红色)
|
||
- 成功:#52c41a (绿色)
|
||
- 警告:#faad14 (琥珀色)
|
||
- 文本层次:#333 / #666 / #999
|
||
|
||
2. **间距系统**
|
||
- 基础单位:4rpx
|
||
- 常用值:20rpx, 24rpx, 32rpx
|
||
- 卡片间距:20rpx
|
||
- 内容内边距:24rpx
|
||
|
||
3. **圆角规范**
|
||
- 卡片:16rpx
|
||
- 按钮:8rpx
|
||
- 徽章:4rpx
|
||
|
||
4. **阴影效果**
|
||
- 卡片:0 2rpx 8rpx rgba(0, 0, 0, 0.05)
|
||
- 固定导航:0 2rpx 8rpx rgba(0, 0, 0, 0.05)
|
||
|
||
### 性能考虑
|
||
|
||
- 使用 `v-if` 而非 `v-show` 处理大列表的条件渲染
|
||
- 商户分组减少渲染节点数量
|
||
- 横向滚动使用 `scroll-view` 组件优化性能
|
||
|
||
### 可访问性
|
||
|
||
- 保持足够的颜色对比度(WCAG AA 标准)
|
||
- 使用语义化的图标
|
||
- 提供清晰的状态反馈
|
||
|
||
### 响应式设计
|
||
|
||
- 使用 rpx 单位适配不同屏幕
|
||
- 固定导航栏考虑 H5 环境的顶部偏移
|
||
- 横向滚动适配小屏幕设备
|