DisabledPersonSelectorWrapper.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import React, { useState, useEffect } from 'react';
  2. import { useQuery } from '@tanstack/react-query';
  3. import { Button } from '@d8d/shared-ui-components/components/ui/button';
  4. import { DisabledPersonSelector } from '@d8d/allin-disability-person-management-ui/components';
  5. import { disabilityClientManager } from '@d8d/allin-disability-person-management-ui/api';
  6. import type { DisabledPersonData } from '@d8d/allin-disability-person-management-ui';
  7. import { X } from 'lucide-react';
  8. interface DisabledPersonSelectorWrapperProps {
  9. value: number | null; // personId
  10. onChange: (value: number | null) => void;
  11. placeholder?: string;
  12. disabled?: boolean;
  13. className?: string;
  14. 'data-testid'?: string;
  15. }
  16. /**
  17. * 残疾人选择器包装组件
  18. *
  19. * 提供单选模式的残疾人选择功能,支持显示已选择的残疾人信息
  20. */
  21. export const DisabledPersonSelectorWrapper: React.FC<DisabledPersonSelectorWrapperProps> = ({
  22. value,
  23. onChange,
  24. placeholder = '请选择残疾人',
  25. disabled = false,
  26. className,
  27. 'data-testid': testId,
  28. }) => {
  29. const [isOpen, setIsOpen] = useState(false);
  30. const [selectedPerson, setSelectedPerson] = useState<DisabledPersonData | null>(null);
  31. // 当 value 变化时,获取残疾人详细信息
  32. useEffect(() => {
  33. if (value) {
  34. // 通过 API 获取残疾人详细信息
  35. disabilityClientManager.get().getDisabledPerson[':id'].$get({
  36. param: { id: value },
  37. }).then(res => {
  38. if (res.status === 200) {
  39. return res.json();
  40. }
  41. return null;
  42. }).then(data => {
  43. if (data) {
  44. setSelectedPerson(data);
  45. }
  46. }).catch(() => {
  47. // 如果获取失败,清空选择
  48. setSelectedPerson(null);
  49. });
  50. } else {
  51. setSelectedPerson(null);
  52. }
  53. }, [value]);
  54. // 处理选择残疾人
  55. const handleSelect = (person: DisabledPersonData | DisabledPersonData[]) => {
  56. const selected = Array.isArray(person) ? person[0] : person;
  57. if (selected) {
  58. setSelectedPerson(selected);
  59. onChange(selected.id);
  60. }
  61. };
  62. // 处理清除选择
  63. const handleClear = (e: React.MouseEvent) => {
  64. e.stopPropagation();
  65. setSelectedPerson(null);
  66. onChange(null);
  67. };
  68. return (
  69. <div className={className} data-testid={testId}>
  70. {/* 显示已选择的残疾人信息或选择按钮 */}
  71. {selectedPerson ? (
  72. <div className="flex items-center gap-2 p-2 border rounded-md bg-background">
  73. <div className="flex-1 min-w-0">
  74. <div className="text-sm font-medium truncate">{selectedPerson.name}</div>
  75. <div className="text-xs text-muted-foreground truncate">
  76. 残疾证号: {selectedPerson.disabilityId}
  77. </div>
  78. </div>
  79. {!disabled && (
  80. <Button
  81. type="button"
  82. variant="ghost"
  83. size="icon"
  84. onClick={handleClear}
  85. className="h-6 w-6 flex-shrink-0"
  86. data-testid="clear-disabled-person-button"
  87. >
  88. <X className="h-4 w-4" />
  89. </Button>
  90. )}
  91. </div>
  92. ) : (
  93. <Button
  94. type="button"
  95. variant="outline"
  96. onClick={() => setIsOpen(true)}
  97. disabled={disabled}
  98. className="w-full justify-start"
  99. data-testid="select-disabled-person-button"
  100. >
  101. {placeholder}
  102. </Button>
  103. )}
  104. {/* 残疾人选择器对话框 */}
  105. <DisabledPersonSelector
  106. open={isOpen}
  107. onOpenChange={setIsOpen}
  108. onSelect={handleSelect}
  109. mode="single"
  110. />
  111. </div>
  112. );
  113. };
  114. export default DisabledPersonSelectorWrapper;