index.tsx 2.18 KB
// REQ-USR-003: 用户列表页面容器(组合工具栏/筛选栏/表格+分页,对接 GET /api/usr/users)
import { useState } from 'react';
import { Button } from 'antd';
import { useNavigate } from 'react-router-dom';
import type { UserVO } from '../../../api/types';
import UserToolbar from './UserToolbar';
import UserFilterBar from './UserFilterBar';
import UserTable from './UserTable';
import { useUserList } from './useUserList';
import { TEXT_ERROR } from './constants';
import styles from './UserList.module.css';

export default function UserListPage() {
  const navigate = useNavigate();
  const {
    list,
    total,
    loading,
    error,
    query,
    exporting,
    search,
    refresh,
    clear,
    setQueryField,
    setMatchType,
    setQueryValue,
    changePage,
    exportExcel,
  } = useUserList();

  // 单选标记仅服务「进单据」语义,不参与查询(spec D8)
  const [selectedRowKey, setSelectedRowKey] = useState<number | null>(null);

  const handleRowDoubleClick = (row: UserVO) => {
    navigate('/usr/users/' + row.id); // BR12
  };

  return (
    <div className={styles.page}>
      <UserToolbar
        onRefresh={refresh}
        onAdd={() => navigate('/usr/users/new')} // BR13
        onExport={() => void exportExcel()}
        exporting={exporting}
        loading={loading}
      />
      <UserFilterBar
        query={query}
        onChangeQueryField={setQueryField}
        onChangeMatchType={setMatchType}
        onChangeQueryValue={setQueryValue}
        onSearch={search}
        onClear={clear}
      />
      {error ? (
        <div className={styles.errorBox} data-testid="userlist-error">
          <span className={styles.errorText}>{TEXT_ERROR}</span>
          <Button type="primary" onClick={() => refresh()}>
            点击重试
          </Button>
        </div>
      ) : (
        <UserTable
          rows={list}
          loading={loading}
          total={total}
          pageNum={query.pageNum}
          pageSize={query.pageSize}
          onChangePage={changePage}
          onRowDoubleClick={handleRowDoubleClick}
          selectedRowKey={selectedRowKey}
          onSelectRow={setSelectedRowKey}
        />
      )}
    </div>
  );
}