MerchantSelector.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import React from 'react';
  2. import { useQuery } from '@tanstack/react-query';
  3. import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/client/components/ui/select';
  4. import { merchantClient } from '@/client/api';
  5. import type { InferResponseType } from 'hono/client';
  6. type Merchant = InferResponseType<typeof merchantClient.$get, 200>['data'][0];
  7. interface MerchantSelectorProps {
  8. value?: number;
  9. onChange?: (value: number | undefined) => void;
  10. placeholder?: string;
  11. disabled?: boolean;
  12. allowClear?: boolean;
  13. }
  14. export const MerchantSelector: React.FC<MerchantSelectorProps> = ({
  15. value,
  16. onChange,
  17. placeholder = '选择商户',
  18. disabled = false,
  19. allowClear = true,
  20. }) => {
  21. const { data, isLoading } = useQuery({
  22. queryKey: ['merchants-select'],
  23. queryFn: async () => {
  24. const res = await merchantClient.$get({
  25. query: { page: 1, pageSize: 100 }
  26. });
  27. if (res.status !== 200) throw new Error('获取商户列表失败');
  28. return await res.json();
  29. },
  30. });
  31. const merchants = data?.data || [];
  32. const handleValueChange = (newValue: string) => {
  33. const numValue = newValue === 'null' ? undefined : parseInt(newValue, 10);
  34. onChange?.(numValue);
  35. };
  36. return (
  37. <Select
  38. value={value?.toString() || (allowClear ? 'null' : undefined)}
  39. onValueChange={handleValueChange}
  40. disabled={disabled}
  41. >
  42. <SelectTrigger>
  43. <SelectValue placeholder={placeholder} />
  44. </SelectTrigger>
  45. <SelectContent>
  46. {allowClear && (
  47. <SelectItem value="null">无</SelectItem>
  48. )}
  49. {merchants.map((merchant) => (
  50. <SelectItem key={merchant.id} value={merchant.id.toString()}>
  51. {merchant.name || merchant.username}
  52. </SelectItem>
  53. ))}
  54. </SelectContent>
  55. </Select>
  56. );
  57. };
  58. export default MerchantSelector;