300 lines
8.1 KiB
Markdown
300 lines
8.1 KiB
Markdown
# Order Status Tabs UI (订单状态标签页UI)
|
|
|
|
## Feature
|
|
Redesigned the fulfillment status filter from a dropdown select to clickable tabs for better user experience and faster filtering.
|
|
|
|
## Changes Made
|
|
|
|
### File: `admin/src/views/consumer/prescription/order_list.vue`
|
|
|
|
#### 1. Replaced Dropdown with Tab UI
|
|
**Before:**
|
|
```vue
|
|
<el-form-item class="w-[180px]" label="履约状态">
|
|
<el-select v-model="queryParams.fulfillment_status" placeholder="全部" clearable>
|
|
<el-option label="待双审通过" :value="1" />
|
|
<el-option label="履约中" :value="2" />
|
|
<el-option label="已发货" :value="5" />
|
|
<el-option label="已完成" :value="3" />
|
|
<el-option label="已取消" :value="4" />
|
|
</el-select>
|
|
</el-form-item>
|
|
```
|
|
|
|
**After:**
|
|
```vue
|
|
<!-- 状态标签页 -->
|
|
<el-card class="!border-none shadow-sm mb-4" shadow="never">
|
|
<div class="flex items-center gap-2 flex-wrap">
|
|
<div
|
|
v-for="tab in statusTabs"
|
|
:key="tab.value"
|
|
:class="[
|
|
'px-4 py-2 rounded-lg cursor-pointer transition-all duration-200 select-none',
|
|
queryParams.fulfillment_status === tab.value
|
|
? 'bg-primary text-white shadow-md'
|
|
: 'bg-gray-50 text-gray-600 hover:bg-gray-100'
|
|
]"
|
|
@click="handleStatusTabClick(tab.value)"
|
|
>
|
|
<div class="flex items-center gap-2">
|
|
<span class="font-medium">{{ tab.label }}</span>
|
|
<span v-if="tab.count !== undefined" :class="[
|
|
'text-xs px-1.5 py-0.5 rounded',
|
|
queryParams.fulfillment_status === tab.value
|
|
? 'bg-white/20'
|
|
: 'bg-gray-200'
|
|
]">
|
|
{{ tab.count }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
```
|
|
|
|
#### 2. Added Status Tabs Configuration
|
|
```typescript
|
|
// 状态标签页配置
|
|
const statusTabs = ref([
|
|
{ label: '全部', value: '' as number | '', count: undefined },
|
|
{ label: '待双审通过', value: 1, count: undefined },
|
|
{ label: '履约中', value: 2, count: undefined },
|
|
{ label: '已发货', value: 5, count: undefined },
|
|
{ label: '已完成', value: 3, count: undefined },
|
|
{ label: '已取消', value: 4, count: undefined }
|
|
])
|
|
```
|
|
|
|
#### 3. Added Click Handler
|
|
```typescript
|
|
// 处理状态标签点击
|
|
const handleStatusTabClick = (value: number | '') => {
|
|
queryParams.fulfillment_status = value
|
|
resetPage()
|
|
}
|
|
```
|
|
|
|
## UI Design
|
|
|
|
### Visual States
|
|
|
|
**Active Tab:**
|
|
- Primary color background (`bg-primary`)
|
|
- White text
|
|
- Shadow effect
|
|
- Badge with semi-transparent white background
|
|
|
|
**Inactive Tab:**
|
|
- Light gray background (`bg-gray-50`)
|
|
- Gray text
|
|
- Hover effect (lighter gray)
|
|
- Badge with gray background
|
|
|
|
### Layout
|
|
- Horizontal flex layout with gap
|
|
- Wraps on smaller screens
|
|
- Smooth transitions (200ms)
|
|
- Rounded corners
|
|
- Consistent padding
|
|
|
|
### Badge (Count Display)
|
|
- Small text size
|
|
- Rounded badge
|
|
- Shows count for each status (optional feature)
|
|
- Different styling for active/inactive states
|
|
|
|
## User Experience Improvements
|
|
|
|
### Before (Dropdown):
|
|
1. User clicks dropdown
|
|
2. Dropdown opens with options
|
|
3. User scrolls to find status
|
|
4. User clicks option
|
|
5. Dropdown closes
|
|
6. User clicks "查询" button
|
|
|
|
**Total: 3-4 clicks + scrolling**
|
|
|
|
### After (Tabs):
|
|
1. User clicks tab
|
|
2. Filter applies immediately
|
|
|
|
**Total: 1 click**
|
|
|
|
### Benefits:
|
|
- ✅ **Faster filtering**: One-click access to any status
|
|
- ✅ **Visual feedback**: Clear indication of current filter
|
|
- ✅ **Better discoverability**: All options visible at once
|
|
- ✅ **No extra clicks**: Auto-triggers search on click
|
|
- ✅ **Modern UI**: Follows common tab pattern
|
|
- ✅ **Mobile friendly**: Wraps on small screens
|
|
|
|
## Features
|
|
|
|
### 1. Active State Indication
|
|
The currently selected tab is highlighted with primary color, making it immediately clear which filter is active.
|
|
|
|
### 2. Hover Effects
|
|
Inactive tabs show a subtle hover effect, indicating they are clickable.
|
|
|
|
### 3. Count Badges (Optional)
|
|
Each tab can display a count badge showing the number of orders in that status. Currently set to `undefined` but can be populated with actual counts.
|
|
|
|
### 4. Responsive Design
|
|
Tabs wrap to multiple lines on smaller screens using `flex-wrap`.
|
|
|
|
### 5. Smooth Transitions
|
|
All state changes have smooth 200ms transitions for a polished feel.
|
|
|
|
## Implementation Details
|
|
|
|
### Tab Configuration
|
|
```typescript
|
|
{
|
|
label: string, // Display text
|
|
value: number | '', // Filter value ('' for "All")
|
|
count: number | undefined // Optional count badge
|
|
}
|
|
```
|
|
|
|
### Click Handler Logic
|
|
```typescript
|
|
const handleStatusTabClick = (value: number | '') => {
|
|
queryParams.fulfillment_status = value // Update filter
|
|
resetPage() // Trigger search
|
|
}
|
|
```
|
|
|
|
### Styling Classes
|
|
- `bg-primary`: Primary brand color (active state)
|
|
- `bg-gray-50`: Light gray (inactive state)
|
|
- `hover:bg-gray-100`: Hover effect
|
|
- `shadow-md`: Shadow for active tab
|
|
- `transition-all duration-200`: Smooth transitions
|
|
- `select-none`: Prevent text selection on click
|
|
|
|
## Future Enhancements
|
|
|
|
### 1. Add Count Badges
|
|
Fetch and display order counts for each status:
|
|
|
|
```typescript
|
|
// After fetching data
|
|
const updateStatusCounts = (data: any) => {
|
|
statusTabs.value[0].count = data.total
|
|
statusTabs.value[1].count = data.pending
|
|
statusTabs.value[2].count = data.processing
|
|
// ... etc
|
|
}
|
|
```
|
|
|
|
### 2. Add Icons
|
|
Add status-specific icons for better visual recognition:
|
|
|
|
```vue
|
|
<svg class="w-4 h-4" v-if="tab.value === 1">
|
|
<!-- Clock icon for pending -->
|
|
</svg>
|
|
```
|
|
|
|
### 3. Add Keyboard Navigation
|
|
Support arrow keys for tab navigation:
|
|
|
|
```typescript
|
|
const handleKeydown = (e: KeyboardEvent) => {
|
|
if (e.key === 'ArrowLeft') {
|
|
// Navigate to previous tab
|
|
} else if (e.key === 'ArrowRight') {
|
|
// Navigate to next tab
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4. Add Loading State
|
|
Show loading indicator on active tab while fetching:
|
|
|
|
```vue
|
|
<el-icon v-if="pager.loading && queryParams.fulfillment_status === tab.value" class="is-loading">
|
|
<Loading />
|
|
</el-icon>
|
|
```
|
|
|
|
## Testing Steps
|
|
|
|
### 1. Test Tab Switching
|
|
1. Open order list page
|
|
2. Click on different status tabs
|
|
3. Verify:
|
|
- Active tab is highlighted
|
|
- Table updates with filtered results
|
|
- URL parameters update (if using router)
|
|
|
|
### 2. Test Visual States
|
|
1. Hover over inactive tabs
|
|
2. Verify hover effect appears
|
|
3. Click a tab
|
|
4. Verify active state styling applies
|
|
|
|
### 3. Test "全部" Tab
|
|
1. Click "全部" tab
|
|
2. Verify all orders are shown
|
|
3. Verify no status filter is applied
|
|
|
|
### 4. Test Responsive Behavior
|
|
1. Resize browser window to small width
|
|
2. Verify tabs wrap to multiple lines
|
|
3. Verify all tabs remain accessible
|
|
|
|
### 5. Test with Search
|
|
1. Enter order number in search
|
|
2. Click different status tabs
|
|
3. Verify both filters work together
|
|
|
|
## Accessibility
|
|
|
|
### Current Implementation:
|
|
- ✅ Keyboard accessible (clickable divs)
|
|
- ✅ Visual feedback on hover
|
|
- ✅ Clear active state indication
|
|
- ✅ Sufficient color contrast
|
|
|
|
### Recommended Improvements:
|
|
- Add `role="tab"` and `aria-selected` attributes
|
|
- Add `tabindex="0"` for keyboard navigation
|
|
- Add keyboard event handlers (Enter/Space)
|
|
- Add `aria-label` for screen readers
|
|
|
|
### Example:
|
|
```vue
|
|
<div
|
|
role="tab"
|
|
:aria-selected="queryParams.fulfillment_status === tab.value"
|
|
:tabindex="0"
|
|
@keydown.enter="handleStatusTabClick(tab.value)"
|
|
@keydown.space.prevent="handleStatusTabClick(tab.value)"
|
|
>
|
|
```
|
|
|
|
## Related Files
|
|
|
|
### Frontend:
|
|
- `admin/src/views/consumer/prescription/order_list.vue`
|
|
- Added status tabs UI
|
|
- Added `statusTabs` configuration
|
|
- Added `handleStatusTabClick` handler
|
|
- Removed dropdown select
|
|
|
|
## Summary
|
|
|
|
✅ Replaced dropdown with clickable tabs
|
|
✅ One-click filtering (no need to click "查询")
|
|
✅ Visual active state indication
|
|
✅ Hover effects for better UX
|
|
✅ Responsive design with flex-wrap
|
|
✅ Smooth transitions
|
|
✅ Support for count badges (optional)
|
|
✅ Cleaner, more modern UI
|
|
|
|
The status filter is now much more intuitive and efficient, following modern UI patterns commonly seen in admin dashboards!
|