Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/pages/DriversPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,30 @@ describe('DriversPage 評價欄(B5)', () => {
});
});
});

describe('DriversPage 評價排序方向', () => {
beforeEach(() => {
setRole('superadmin');
mockFetchDrivers.mockReset();
mockFetchDrivers.mockResolvedValue([
{ ID: 1, Name: '高分司機', Phone: '', LineUserID: 'l1', Status: 1, RatingAvg: 4.8, RatingCount: 25 },
{ ID: 2, Name: '低分司機', Phone: '', LineUserID: 'l2', Status: 1, RatingAvg: 2.5, RatingCount: 4 },
{ ID: 3, Name: '新司機', Phone: '', LineUserID: 'l3', Status: 1, RatingAvg: 0, RatingCount: 0 },
]);
});

// 迴歸:antd 做降序是把比較結果整個反轉,特例不跟著反轉的話沒評分的會浮到最前面。
it('降序時沒評分的仍排最後(antd 會反轉比較結果)', async () => {
const user = userEvent.setup();
renderWithProviders(<DriversPage />);
await waitFor(() => expect(screen.getByText('高分司機')).toBeInTheDocument());

await user.click(screen.getByText('評價')); // 升序
await user.click(screen.getByText('評價')); // 降序

await waitFor(() => {
const names = screen.getAllByRole('row').slice(1).map((r) => r.querySelector('a')?.textContent ?? '');
expect(names).toEqual(['高分司機', '低分司機', '新司機']);
});
});
});
14 changes: 10 additions & 4 deletions src/pages/DriversPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { App, Button, Card, Empty, Input, Select, Space, Switch, Table, Tag, Tooltip } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { SortOrder } from 'antd/es/table/interface';
import { Link } from 'react-router-dom';
import { StarFilled } from '@ant-design/icons';

Expand Down Expand Up @@ -197,11 +198,16 @@ export default function DriversPage() {
title: '評價',
width: 120,
// 可排序:營運要能一眼找出評價最低的司機,那正是這一欄存在的理由。
// **沒評分的排在最後**(不是最前)——0 則不代表差,不該混進低分名單。
sorter: (a: Driver, b: Driver) => {
// **沒評分的兩個方向都排最後**(不是最前)——0 則不代表差,不該混進低分名單。
//
// `sortOrder` 不可省:antd 做降序的方式是**把比較結果整個反轉**,
// 所以「沉底」的特例不跟著反轉的話,降序時沒評分的會被推到最前面
// (2026-07-27 實測:降序得到「新司機, 高分司機, 低分司機」)。
sorter: (a: Driver, b: Driver, sortOrder?: SortOrder) => {
const sink = sortOrder === 'descend' ? -1 : 1; // 讓「沒評分」永遠沉底
if (a.RatingCount === 0 && b.RatingCount === 0) return 0;
if (a.RatingCount === 0) return 1;
if (b.RatingCount === 0) return -1;
if (a.RatingCount === 0) return sink;
if (b.RatingCount === 0) return -sink;
return a.RatingAvg - b.RatingAvg;
},
render: (_: unknown, driver: Driver) =>
Expand Down
Loading