Files
zyt/ORDER_STATUS_TABS_UI.md
T
2026-04-17 09:47:17 +08:00

8.1 KiB

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:

<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:

<!-- 状态标签页 -->
<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

// 状态标签页配置
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

// 处理状态标签点击
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

{
    label: string,      // Display text
    value: number | '', // Filter value ('' for "All")
    count: number | undefined  // Optional count badge
}

Click Handler Logic

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:

// 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:

<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:

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:

<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
  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
  • 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:

<div
    role="tab"
    :aria-selected="queryParams.fulfillment_status === tab.value"
    :tabindex="0"
    @keydown.enter="handleStatusTabClick(tab.value)"
    @keydown.space.prevent="handleStatusTabClick(tab.value)"
>

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!