| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import React, { useState } from 'react';
- import { useQuery } from '@tanstack/react-query';
- import { Select, Spin } from 'antd';
- import type { SelectProps } from 'antd';
- import { InferResponseType } from 'hono/client';
- import { hetongClient } from '@/client/api';
- // 定义合同数据类型
- type ContractItem = InferResponseType<typeof hetongClient[':id']['$get'], 200>;
- type ContractListResponse = InferResponseType<typeof hetongClient.$get, 200>;
- // 定义组件属性接口
- interface ContractSelectProps {
- value?: number;
- onChange?: (value?: number) => void;
- placeholder?: string;
- disabled?: boolean;
- }
- const ContractSelect: React.FC<ContractSelectProps> = ({
- value,
- onChange,
- placeholder = '请选择合同',
- disabled = false
- }) => {
- const [searchValue, setSearchValue] = useState('');
- // 使用React Query获取合同列表数据
- const { data: contractsData, isLoading, error } = useQuery<ContractListResponse>({
- queryKey: ['contracts', searchValue],
- queryFn: async () => {
- const res = await hetongClient.$get({
- query: {
- page: 1,
- pageSize: 1000,
- keyword: searchValue
- }
- });
-
- if (!res.ok) {
- throw new Error('获取合同列表失败');
- }
-
- return res.json();
- },
- });
- // 处理搜索输入变化
- const handleSearch = (value: string) => {
- setSearchValue(value);
- };
- // 格式化合同数据为Select组件所需的选项格式
- const options = contractsData?.data?.map(contract => ({
- label: `${contract.contractNumber} - ${contract.client?.name || '未知客户'}`,
- value: contract.id,
- })) || [];
- return (
- <div style={{ position: 'relative' }}>
- <Select
- value={value}
- onChange={onChange}
- placeholder={placeholder}
- disabled={disabled || isLoading}
- showSearch
- filterOption={false}
- onSearch={handleSearch}
- style={{ width: '100%' }}
- options={options}
- notFoundContent={isLoading ? <Spin size="small" /> : '未找到匹配合同'}
- />
- {isLoading && (
- <div style={{
- position: 'absolute',
- top: '50%',
- right: '16px',
- transform: 'translateY(-50%)',
- pointerEvents: 'none'
- }}>
- <Spin size="small" />
- </div>
- )}
- </div>
- );
- };
- export default ContractSelect;
|