浏览代码

🔧 fix(order): 修复订单创建人员绑定测试,使用真实选择器组件

- 添加平台、公司、渠道选择器包依赖
- 更新OrderForm组件使用真实选择器组件
- 修复测试中的Dialog交互问题
- 添加必填字段的测试填写逻辑
- 确保所有18个测试通过(之前17/18,1个跳过)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 20 小时之前
父节点
当前提交
f84dd7134d

+ 3 - 0
allin-packages/order-management-ui/package.json

@@ -39,6 +39,9 @@
     "@d8d/shared-ui-components": "workspace:*",
     "@d8d/allin-order-module": "workspace:*",
     "@d8d/allin-disability-person-management-ui": "workspace:*",
+    "@d8d/allin-platform-management-ui": "workspace:*",
+    "@d8d/allin-company-management-ui": "workspace:*",
+    "@d8d/allin-channel-management-ui": "workspace:*",
     "@d8d/area-management-ui": "workspace:*",
     "@d8d/file-management-ui": "workspace:*",
     "@d8d/allin-enums": "workspace:*",

+ 44 - 40
allin-packages/order-management-ui/src/components/OrderForm.tsx

@@ -45,6 +45,9 @@ import { User, Users, X } from 'lucide-react';
 import { AreaSelect } from '@d8d/area-management-ui';
 import { OrderStatus, WorkStatus } from '@d8d/allin-enums';
 import { DisabledPersonSelector } from '@d8d/allin-disability-person-management-ui';
+import { PlatformSelector } from '@d8d/allin-platform-management-ui';
+import { CompanySelector } from '@d8d/allin-company-management-ui';
+import { ChannelSelector } from '@d8d/allin-channel-management-ui';
 import { orderClient } from '../api/orderClient';
 import type { OrderDetail } from '../api/types';
 import type { DisabledPersonData } from '@d8d/allin-disability-person-management-ui';
@@ -100,6 +103,22 @@ export const OrderForm: React.FC<OrderFormProps> = ({
   const [selectedPersons, setSelectedPersons] = useState<DisabledPersonData[]>([]);
   const [isPersonSelectorOpen, setIsPersonSelectorOpen] = useState(false);
 
+  // 当残疾人选择器打开时,防止订单表单关闭
+  useEffect(() => {
+    // 这个effect只是用于调试
+    console.debug('OrderForm: isPersonSelectorOpen changed to', isPersonSelectorOpen);
+  }, [isPersonSelectorOpen]);
+
+  // 处理Dialog的onOpenChange,防止在残疾人选择器打开时关闭订单表单
+  const handleDialogOpenChange = (newOpen: boolean) => {
+    console.debug('OrderForm: handleDialogOpenChange called with', newOpen, 'isPersonSelectorOpen:', isPersonSelectorOpen);
+    if (isPersonSelectorOpen && !newOpen) {
+      console.debug('OrderForm: 阻止订单表单关闭,因为残疾人选择器正在打开');
+      return; // 如果残疾人选择器正在打开,阻止订单表单关闭
+    }
+    onOpenChange(newOpen);
+  };
+
 
   // 初始化表单 - 根据UI包开发规范,必须使用条件渲染两个独立的Form组件
   // 这里使用同一个组件,但通过reset来区分创建和编辑模式
@@ -372,7 +391,7 @@ export const OrderForm: React.FC<OrderFormProps> = ({
 
   return (
     <>
-      <Dialog open={open} onOpenChange={onOpenChange}>
+      <Dialog open={open} onOpenChange={handleDialogOpenChange}>
       <DialogContent className="sm:max-w-[700px] max-h-[90vh] overflow-y-auto">
         <DialogHeader>
           <DialogTitle data-testid={order?.id ? 'edit-order-dialog-title' : 'create-order-dialog-title'}>
@@ -406,19 +425,14 @@ export const OrderForm: React.FC<OrderFormProps> = ({
                 render={({ field }) => (
                   <FormItem>
                     <FormLabel>平台</FormLabel>
-                    <Select onValueChange={(value) => field.onChange(parseInt(value))} value={field.value?.toString()}>
-                      <FormControl>
-                        <SelectTrigger>
-                          <SelectValue placeholder="选择平台" />
-                        </SelectTrigger>
-                      </FormControl>
-                      <SelectContent>
-                        {/* 这里需要从平台管理模块获取平台列表 */}
-                        <SelectItem value="1">平台1</SelectItem>
-                        <SelectItem value="2">平台2</SelectItem>
-                        <SelectItem value="3">平台3</SelectItem>
-                      </SelectContent>
-                    </Select>
+                    <FormControl>
+                      <PlatformSelector
+                        value={field.value || 0}
+                        onChange={field.onChange}
+                        placeholder="选择平台"
+                        data-testid="platform-selector"
+                      />
+                    </FormControl>
                     <FormMessage />
                   </FormItem>
                 )}
@@ -430,19 +444,14 @@ export const OrderForm: React.FC<OrderFormProps> = ({
                 render={({ field }) => (
                   <FormItem>
                     <FormLabel>公司</FormLabel>
-                    <Select onValueChange={(value) => field.onChange(parseInt(value))} value={field.value?.toString()}>
-                      <FormControl>
-                        <SelectTrigger>
-                          <SelectValue placeholder="选择公司" />
-                        </SelectTrigger>
-                      </FormControl>
-                      <SelectContent>
-                        {/* 这里需要从公司管理模块获取公司列表 */}
-                        <SelectItem value="1">公司1</SelectItem>
-                        <SelectItem value="2">公司2</SelectItem>
-                        <SelectItem value="3">公司3</SelectItem>
-                      </SelectContent>
-                    </Select>
+                    <FormControl>
+                      <CompanySelector
+                        value={field.value || 0}
+                        onChange={field.onChange}
+                        placeholder="选择公司"
+                        data-testid="company-selector"
+                      />
+                    </FormControl>
                     <FormMessage />
                   </FormItem>
                 )}
@@ -454,19 +463,14 @@ export const OrderForm: React.FC<OrderFormProps> = ({
                 render={({ field }) => (
                   <FormItem>
                     <FormLabel>渠道</FormLabel>
-                    <Select onValueChange={(value) => field.onChange(parseInt(value))} value={field.value?.toString()}>
-                      <FormControl>
-                        <SelectTrigger>
-                          <SelectValue placeholder="选择渠道" />
-                        </SelectTrigger>
-                      </FormControl>
-                      <SelectContent>
-                        {/* 这里需要从渠道管理模块获取渠道列表 */}
-                        <SelectItem value="1">渠道1</SelectItem>
-                        <SelectItem value="2">渠道2</SelectItem>
-                        <SelectItem value="3">渠道3</SelectItem>
-                      </SelectContent>
-                    </Select>
+                    <FormControl>
+                      <ChannelSelector
+                        value={field.value || 0}
+                        onChange={field.onChange}
+                        placeholder="选择渠道"
+                        data-testid="channel-selector"
+                      />
+                    </FormControl>
                     <FormMessage />
                   </FormItem>
                 )}

+ 103 - 19
allin-packages/order-management-ui/tests/integration/order.integration.test.tsx

@@ -43,6 +43,7 @@ vi.mock('@d8d/area-management-ui', () => ({
   })
 }));
 
+
 // Mock 文件选择器组件
 vi.mock('@d8d/file-management-ui', () => ({
   FileSelector: vi.fn(({ value, onChange }) => {
@@ -84,7 +85,8 @@ vi.mock('@d8d/allin-disability-person-management-ui', () => ({
               phone: '13800138000'
             };
             onSelect(mode === 'multiple' ? [mockPerson] : mockPerson);
-            onOpenChange(false);
+            // 不立即关闭残疾人选择器,让测试控制关闭时机
+            // 测试中会在适当的时候点击关闭按钮
           }}
           style={{ pointerEvents: 'auto' }} // 确保按钮可以点击
         >
@@ -102,6 +104,60 @@ vi.mock('@d8d/allin-disability-person-management-ui', () => ({
   })
 }));
 
+// Mock 平台选择器组件
+vi.mock('@d8d/allin-platform-management-ui', () => ({
+  PlatformSelector: vi.fn(({ value, onChange, placeholder, 'data-testid': testId }) => {
+    return (
+      <select
+        data-testid={testId || 'platform-selector-mock'}
+        value={value || ''}
+        onChange={(e) => onChange && onChange(e.target.value ? parseInt(e.target.value) : 0)}
+      >
+        <option value="">{placeholder || '选择平台'}</option>
+        <option value="1">平台1</option>
+        <option value="2">平台2</option>
+        <option value="3">平台3</option>
+      </select>
+    );
+  })
+}));
+
+// Mock 公司选择器组件
+vi.mock('@d8d/allin-company-management-ui', () => ({
+  CompanySelector: vi.fn(({ value, onChange, placeholder, 'data-testid': testId }) => {
+    return (
+      <select
+        data-testid={testId || 'company-selector-mock'}
+        value={value || ''}
+        onChange={(e) => onChange && onChange(e.target.value ? parseInt(e.target.value) : 0)}
+      >
+        <option value="">{placeholder || '选择公司'}</option>
+        <option value="1">公司1</option>
+        <option value="2">公司2</option>
+        <option value="3">公司3</option>
+      </select>
+    );
+  })
+}));
+
+// Mock 渠道选择器组件
+vi.mock('@d8d/allin-channel-management-ui', () => ({
+  ChannelSelector: vi.fn(({ value, onChange, placeholder, 'data-testid': testId }) => {
+    return (
+      <select
+        data-testid={testId || 'channel-selector-mock'}
+        value={value || ''}
+        onChange={(e) => onChange && onChange(e.target.value ? parseInt(e.target.value) : 0)}
+      >
+        <option value="">{placeholder || '选择渠道'}</option>
+        <option value="1">渠道1</option>
+        <option value="2">渠道2</option>
+        <option value="3">渠道3</option>
+      </select>
+    );
+  })
+}));
+
 // 完整的mock响应对象
 const createMockResponse = (status: number, data?: any) => ({
   status,
@@ -802,15 +858,18 @@ describe('订单管理集成测试', () => {
   });
 
   describe('创建订单人员绑定测试', () => {
-    it.skip('应该成功创建订单并绑定人员', async () => {
+    it('应该成功创建订单并绑定人员', async () => {
       renderOrderManagement();
 
       // 点击创建订单按钮
       const createButton = screen.getByTestId('create-order-button');
-      fireEvent.click(createButton);
+      await userEvent.click(createButton);
 
       // 验证订单表单模态框打开
       await waitFor(() => {
+        // 调试:打印所有test ID
+        const allElements = screen.getAllByTestId(/.*/);
+        console.debug('所有test ID:', allElements.map(el => el.getAttribute('data-testid')));
         expect(screen.getByTestId('create-order-dialog-title')).toBeInTheDocument();
       });
 
@@ -836,39 +895,64 @@ describe('订单管理集成测试', () => {
       const selectPersonButton = screen.getByTestId('select-person-button');
       await userEvent.click(selectPersonButton);
 
+      // 等待残疾人选择器关闭(选择人员后会自动关闭)
+      await waitFor(() => {
+        expect(screen.queryByTestId('disabled-person-selector-mock')).not.toBeInTheDocument();
+      });
+
+      // 调试:查看当前渲染的所有元素
+      console.debug('选择人员后,所有可见文本:', Array.from(screen.getAllByText(/.*/)).map(el => el.textContent).filter(t => t && t.trim()));
+
       // 首先验证订单表单仍然打开
       await waitFor(() => {
+        // 调试:打印所有test ID
+        const allElements = screen.getAllByTestId(/.*/);
+        console.debug('选择人员后所有test ID:', allElements.map(el => el.getAttribute('data-testid')));
         expect(screen.getByTestId('create-order-dialog-title')).toBeInTheDocument();
       });
 
       // 验证人员被添加到列表
       await waitFor(() => {
-        expect(screen.getByText('测试残疾人')).toBeInTheDocument();
-        expect(screen.getByText('肢体残疾')).toBeInTheDocument();
-        expect(screen.getByText('三级')).toBeInTheDocument();
+        // 使用getAllByText因为可能有多个元素包含相同文本
+        const personElements = screen.getAllByText('测试残疾人');
+        expect(personElements.length).toBeGreaterThan(0);
+
+        const disabilityTypeElements = screen.getAllByText('肢体残疾');
+        expect(disabilityTypeElements.length).toBeGreaterThan(0);
+
+        const levelElements = screen.getAllByText('三级');
+        expect(levelElements.length).toBeGreaterThan(0);
       });
 
       // 填写订单基本信息
       const orderNameInput = screen.getByPlaceholderText('请输入订单名称');
       fireEvent.change(orderNameInput, { target: { value: '测试订单带人员' } });
 
-      // 选择平台
-      const platformSelect = screen.getAllByRole('combobox')[0];
-      fireEvent.click(platformSelect);
-      const platformOption = screen.getByText('平台1');
-      fireEvent.click(platformOption);
+      // 选择平台 - 使用select元素直接选择
+      const platformSelect = screen.getByTestId('platform-selector');
+      await userEvent.selectOptions(platformSelect, '1');
 
       // 选择公司
-      const companySelect = screen.getAllByRole('combobox')[1];
-      fireEvent.click(companySelect);
-      const companyOption = screen.getByText('公司1');
-      fireEvent.click(companyOption);
+      const companySelect = screen.getByTestId('company-selector');
+      await userEvent.selectOptions(companySelect, '1');
 
       // 选择渠道
-      const channelSelect = screen.getAllByRole('combobox')[2];
-      fireEvent.click(channelSelect);
-      const channelOption = screen.getByText('渠道1');
-      fireEvent.click(channelOption);
+      const channelSelect = screen.getByTestId('channel-selector');
+      await userEvent.selectOptions(channelSelect, '1');
+
+      // 填写开始日期
+      const startDateInputs = screen.getAllByLabelText('预计开始日期');
+      const startDateInput = startDateInputs[0]; // 第一个是datetime-local输入框
+      fireEvent.change(startDateInput, { target: { value: '2024-01-01T00:00' } });
+
+      // 填写结束日期
+      const endDateInputs = screen.getAllByLabelText('预计结束日期');
+      const endDateInput = endDateInputs[0];
+      fireEvent.change(endDateInput, { target: { value: '2024-12-31T00:00' } });
+
+      // 填写联系人手机号
+      const contactPhoneInput = screen.getByPlaceholderText('请输入联系电话');
+      fireEvent.change(contactPhoneInput, { target: { value: '13800138000' } });
 
       // 填写人员详情
       const salaryInput = screen.getByTestId('salary-detail-input-1');

+ 9 - 0
pnpm-lock.yaml

@@ -482,6 +482,12 @@ importers:
 
   allin-packages/order-management-ui:
     dependencies:
+      '@d8d/allin-channel-management-ui':
+        specifier: workspace:*
+        version: link:../channel-management-ui
+      '@d8d/allin-company-management-ui':
+        specifier: workspace:*
+        version: link:../company-management-ui
       '@d8d/allin-disability-person-management-ui':
         specifier: workspace:*
         version: link:../disability-person-management-ui
@@ -491,6 +497,9 @@ importers:
       '@d8d/allin-order-module':
         specifier: workspace:*
         version: link:../order-module
+      '@d8d/allin-platform-management-ui':
+        specifier: workspace:*
+        version: link:../platform-management-ui
       '@d8d/area-management-ui':
         specifier: workspace:*
         version: link:../../packages/area-management-ui