Forráskód Böngészése

修复ios的触摸模式

pm 1 hónapja
szülő
commit
49943da9be
1 módosított fájl, 113 hozzáadás és 42 törlés
  1. 113 42
      src/components/IsolationWork.tsx

+ 113 - 42
src/components/IsolationWork.tsx

@@ -626,6 +626,43 @@ export default function IsolationWork({ subMenu }: IsolationWorkProps) {
   // 流程设计列表数据(用于流程模板下拉框)
   const [workflowTemplateList, setWorkflowTemplateList] = useState<WorkflowDesignVO[]>([]);
 
+  // iPad(iOS Safari) 触摸场景:点击页面空白处不会触发 Select blur,导致下拉不收起
+  const workflowTemplateSelectWrapRef = useRef<HTMLDivElement | null>(null);
+  const jobCategorySelectWrapRef = useRef<HTMLDivElement | null>(null);
+  const workflowTemplateSelectRef = useRef<any>(null);
+  const jobCategorySelectRef = useRef<any>(null);
+  const [workflowTemplateDropdownVisible, setWorkflowTemplateDropdownVisible] = useState(false);
+  const [jobCategoryDropdownVisible, setJobCategoryDropdownVisible] = useState(false);
+
+  useEffect(() => {
+    if (!workflowTemplateDropdownVisible && !jobCategoryDropdownVisible) return;
+
+    const closeIfPointerOutside = (evt: Event) => {
+      const target = (evt.target as HTMLElement | null);
+      if (!target) return;
+
+      const inWrap =
+        (workflowTemplateSelectWrapRef.current && workflowTemplateSelectWrapRef.current.contains(target)) ||
+        (jobCategorySelectWrapRef.current && jobCategorySelectWrapRef.current.contains(target));
+      const inDropdown = !!target.closest?.('.ant-select-dropdown');
+
+      if (!inWrap && !inDropdown) {
+        // 不控制 open,直接 blur 让 antd 自己收起下拉,避免影响 Form 取值
+        workflowTemplateSelectRef.current?.blur?.();
+        jobCategorySelectRef.current?.blur?.();
+        setWorkflowTemplateDropdownVisible(false);
+        setJobCategoryDropdownVisible(false);
+      }
+    };
+
+    document.addEventListener('touchstart', closeIfPointerOutside, { passive: true });
+    document.addEventListener('mousedown', closeIfPointerOutside);
+    return () => {
+      document.removeEventListener('touchstart', closeIfPointerOutside as any);
+      document.removeEventListener('mousedown', closeIfPointerOutside as any);
+    };
+  }, [workflowTemplateDropdownVisible, jobCategoryDropdownVisible]);
+
   // 作业管理列表数据
   const [workJobList, setWorkJobList] = useState<WorkJobVO[]>([]);
   const [workJobTotal, setWorkJobTotal] = useState(0);
@@ -4505,56 +4542,80 @@ export default function IsolationWork({ subMenu }: IsolationWorkProps) {
                     >
                     <Form.Item
                       label={t('common.workflowTemplate')}
-                      name="workflowTemplate"
                       required
-                      rules={[{ required: true, message: t('common.workflowTemplateRequired') }]}
-                      help={t('common.workflowTemplateHelp')}
+                      extra={t('common.workflowTemplateHelp')}
                     >
-                      <Select
-                        placeholder={t('common.workflowTemplatePlaceholder')}
-                        allowClear
-                        showSearch
-                        disabled={isViewMode}
-                        filterOption={(input, option) =>
-                          (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
-                        }
-                        options={workflowTemplateList
-                          .filter(item => item.status === 1) // 只显示启用的
-                          .map(item => ({
-                            label: item.name,
-                            value: item.id,
-                          }))}
-                        onChange={(value) => {
-                          if (value) {
-                            // 加载流程设计JSON
-                            loadWorkflowJson(value);
-                            // 自动填充作业名称为流程模板名称
-                            const selectedTemplate = workflowTemplateList.find(item => item.id === value);
-                            if (selectedTemplate?.name) {
-                              workJobBasicForm.setFieldsValue({ jobName: selectedTemplate.name });
+                      <div ref={workflowTemplateSelectWrapRef}>
+                        <Form.Item
+                          name="workflowTemplate"
+                          noStyle
+                          rules={[{ required: true, message: t('common.workflowTemplateRequired') }]}
+                        >
+                          <Select
+                            ref={workflowTemplateSelectRef}
+                            placeholder={t('common.workflowTemplatePlaceholder')}
+                            allowClear
+                            showSearch
+                            disabled={isViewMode}
+                            onDropdownVisibleChange={setWorkflowTemplateDropdownVisible}
+                            onClear={() => setWorkflowTemplateDropdownVisible(false)}
+                            filterOption={(input, option) =>
+                              (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
                             }
-                          } else {
-                            setWorkflowJson(null);
-                            // 清空作业名称
-                            workJobBasicForm.setFieldsValue({ jobName: '' });
-                          }
-                        }}
-                      />
+                            options={workflowTemplateList
+                              .filter(item => item.status === 1) // 只显示启用的
+                              .map(item => ({
+                                label: item.name,
+                                value: item.id,
+                              }))}
+                            onChange={(value) => {
+                              setWorkflowTemplateDropdownVisible(false);
+                              if (value) {
+                                // 加载流程设计JSON
+                                loadWorkflowJson(value);
+                                // 自动填充作业名称为流程模板名称
+                                const selectedTemplate = workflowTemplateList.find(item => item.id === value);
+                                if (selectedTemplate?.name) {
+                                  workJobBasicForm.setFieldsValue({ jobName: selectedTemplate.name });
+                                }
+                              } else {
+                                setWorkflowJson(null);
+                                // 清空作业名称
+                                workJobBasicForm.setFieldsValue({ jobName: '' });
+                              }
+                            }}
+                          />
+                        </Form.Item>
+                      </div>
                     </Form.Item>
 
                     <Form.Item
                       label={t('common.jobCategory')}
-                      name="jobCategory"
                       required
-                      rules={[{ required: true, message: t('common.jobCategoryRequired') }]}
                     >
-                      <Select placeholder={t('common.jobCategoryPlaceholder')} allowClear disabled={isViewMode}>
-                        {workTypeDictList.map((item) => (
-                          <Select.Option key={item.id} value={item.value}>
-                            {item.label}
-                          </Select.Option>
-                        ))}
-                      </Select>
+                      <div ref={jobCategorySelectWrapRef}>
+                        <Form.Item
+                          name="jobCategory"
+                          noStyle
+                          rules={[{ required: true, message: t('common.jobCategoryRequired') }]}
+                        >
+                          <Select
+                            ref={jobCategorySelectRef}
+                            placeholder={t('common.jobCategoryPlaceholder')}
+                            allowClear
+                            disabled={isViewMode}
+                            onDropdownVisibleChange={setJobCategoryDropdownVisible}
+                            onSelect={() => setJobCategoryDropdownVisible(false)}
+                            onClear={() => setJobCategoryDropdownVisible(false)}
+                          >
+                            {workTypeDictList.map((item) => (
+                              <Select.Option key={item.id} value={item.value}>
+                                {item.label}
+                              </Select.Option>
+                            ))}
+                          </Select>
+                        </Form.Item>
+                      </div>
                     </Form.Item>
 
                     <Form.Item
@@ -4983,9 +5044,19 @@ export default function IsolationWork({ subMenu }: IsolationWorkProps) {
                                             const isolationNodes = workflowNodes.filter(n => n.data?.type === 'isolation');
                                             
                                             // 如果有连线,只显示已连线的隔离节点;否则显示所有隔离节点(兼容旧数据)
-                                            const nodesToShow = connectedIsolationNodeIds.size > 0
+                                            let nodesToShow = connectedIsolationNodeIds.size > 0
                                               ? isolationNodes.filter(n => connectedIsolationNodeIds.has(String(n.id)))
                                               : isolationNodes;
+
+                                            // 关键兼容:如果当前已经有选中的隔离节点,但它不在过滤结果里
+                                            // antd Select 会回显 raw value(比如 isolation-xxxx)。这里强制把它补进 options,保证回显为节点名称。
+                                            const selectedId = workflowNodeConfig.isolationNodeUuid;
+                                            if (selectedId && !nodesToShow.some(n => String(n.id) === String(selectedId))) {
+                                              const selectedNode = isolationNodes.find(n => String(n.id) === String(selectedId));
+                                              if (selectedNode) {
+                                                nodesToShow = [selectedNode, ...nodesToShow];
+                                              }
+                                            }
                                             
                                             return nodesToShow.map(node => {
                                               // 从 workflowWorkNodeDOList 中查找对应的节点数据,获取 nodeName