更新
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
# 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!
|
||||
Reference in New Issue
Block a user