wyn il y a 3 mois
Parent
commit
534aa0c6a9
1 fichiers modifiés avec 137 ajouts et 83 suppressions
  1. 137 83
      src/components/WorkJobDetail.tsx

+ 137 - 83
src/components/WorkJobDetail.tsx

@@ -1368,16 +1368,47 @@ const NodeInfoPanel: React.FC<NodeInfoPanelProps> = ({
   const workNode = workflowWorkNodeDOList.find(n => n.uuid === node.id);
   const nodeData = node.data || {};
   
+  // 如果是解除隔离节点,需要从对应的隔离方案节点获取数据
+  let isolationNodeData: any = null;
+  if (nodeData.type === 'releaseIsolation') {
+    // 优先使用从隔离方案节点复制的数据(在 loadDesignContentToReactFlow 中已处理)
+    isolationNodeData = nodeData.isolationNodeData;
+    
+    // 如果没有复制的数据,尝试从 isolationNodeUuid 查找对应的隔离方案节点
+    if (!isolationNodeData) {
+      const isolationNodeUuid = workNode?.isolationNodeUuid || nodeData.isolationNodeUuid || '';
+      if (isolationNodeUuid) {
+        const isolationWorkNode = workflowWorkNodeDOList.find(n => n.uuid === isolationNodeUuid && n.type === 'isolation');
+        if (isolationWorkNode) {
+          isolationNodeData = {
+            isolationType: isolationWorkNode.isolationType || '',
+            isolationPoints: isolationWorkNode.isolationPoints 
+              ? (typeof isolationWorkNode.isolationPoints === 'string' 
+                  ? JSON.parse(isolationWorkNode.isolationPoints) 
+                  : isolationWorkNode.isolationPoints)
+              : [],
+            lockPerson: isolationWorkNode.nodeUserList?.find((u: any) => u.type === 'locker' || u.type === 'jtlocker')?.userId || '',
+            coLockPersons: isolationWorkNode.nodeUserList?.filter((u: any) => u.type === 'colocker' || u.type === 'jtcolocker').map((u: any) => u.userId) || [],
+            formId: isolationWorkNode.formId || '',
+            workerUserId: isolationWorkNode.workerUserId || '',
+            points: isolationWorkNode.points || [],
+            locks: isolationWorkNode.locks || [],
+          };
+        }
+      }
+    }
+  }
+  
   // 获取节点配置信息
   const nodeConfig = {
     nodeName: workNode?.nodeName || nodeData.label || nodeData.nodeName || '',
-    responsible: workNode?.workerUserId || nodeData.workerUserId || nodeData.responsible || '',
-    formId: workNode?.formId || nodeData.formId || nodeData.submitForm || '',
-    isolationType: workNode?.isolationType || nodeData.isolationType || '',
-    isolationPoints: workNode?.isolationPoints ? (typeof workNode.isolationPoints === 'string' ? JSON.parse(workNode.isolationPoints) : workNode.isolationPoints) : (nodeData.isolationPoints || []),
+    responsible: isolationNodeData?.workerUserId || workNode?.workerUserId || nodeData.workerUserId || nodeData.responsible || '',
+    formId: isolationNodeData?.formId || workNode?.formId || nodeData.formId || nodeData.submitForm || '',
+    isolationType: isolationNodeData?.isolationType || workNode?.isolationType || nodeData.isolationType || '',
+    isolationPoints: isolationNodeData?.isolationPoints || (workNode?.isolationPoints ? (typeof workNode.isolationPoints === 'string' ? JSON.parse(workNode.isolationPoints) : workNode.isolationPoints) : (nodeData.isolationPoints || [])),
     isolationNodeUuid: workNode?.isolationNodeUuid || nodeData.isolationNodeUuid || '',
-    lockPerson: workNode?.nodeUserList?.find((u: any) => u.type === 'locker' || u.type === 'jtlocker')?.userId || nodeData.lockPerson || '',
-    coLockPersons: workNode?.nodeUserList?.filter((u: any) => u.type === 'colocker' || u.type === 'jtcolocker').map((u: any) => u.userId) || nodeData.coLockPersons || [],
+    lockPerson: isolationNodeData?.lockPerson || workNode?.nodeUserList?.find((u: any) => u.type === 'locker' || u.type === 'jtlocker')?.userId || nodeData.lockPerson || '',
+    coLockPersons: isolationNodeData?.coLockPersons || workNode?.nodeUserList?.filter((u: any) => u.type === 'colocker' || u.type === 'jtcolocker').map((u: any) => u.userId) || nodeData.coLockPersons || [],
     notificationMethods: nodeData.notificationMethods || {
       sms: false,
       message: false,
@@ -1387,6 +1418,9 @@ const NodeInfoPanel: React.FC<NodeInfoPanelProps> = ({
     notificationPerson: nodeData.notificationPerson || '',
     notificationTime: workNode?.notifyTime || nodeData.notificationTime || '',
     remark: nodeData.remark || '',
+    // 保存隔离方案节点的 points 和 locks 数据(用于解除隔离节点显示)
+    points: isolationNodeData?.points || workNode?.points || [],
+    locks: isolationNodeData?.locks || workNode?.locks || [],
   };
 
   // 获取负责人名称
@@ -1441,35 +1475,6 @@ const NodeInfoPanel: React.FC<NodeInfoPanelProps> = ({
     return names.join(', ');
   };
 
-  // 获取通知人显示文本
-  const getNotificationPersonText = () => {
-    const map: Record<string, string> = {
-      'taskResponsible': '任务负责人',
-      'taskParticipant': '任务参与人',
-      'responsibleAndParticipant': '负责人和参与人',
-      'specifiedPerson': '指定人',
-    };
-    return map[nodeConfig.notificationPerson] || nodeConfig.notificationPerson || '-';
-  };
-
-  // 获取通知时间显示文本
-  const getNotificationTimeText = () => {
-    const map: Record<string, string> = {
-      'before': '执行前(上一个节点结束后)',
-      'after': '执行后(该节点结束后)',
-      'time': '选择时间',
-      '30min': '任务开始前30分钟',
-      '1h': '任务开始前1小时',
-      '2h': '任务开始前2小时',
-      '4h': '任务开始前4小时',
-      '5h': '任务开始前5小时',
-      '8h': '任务开始前8小时',
-      '12h': '任务开始前12小时',
-      '24h': '任务开始前24小时',
-      '48h': '任务开始前48小时',
-    };
-    return map[nodeConfig.notificationTime] || nodeConfig.notificationTime || '-';
-  };
 
   return (
     <div className="flex-1 overflow-y-auto space-y-6">
@@ -1652,22 +1657,6 @@ const NodeInfoPanel: React.FC<NodeInfoPanelProps> = ({
                 </div>
               </div>
             </div>
-            <div>
-              <label className="block text-sm font-medium text-gray-700 mb-2">
-                通知人
-              </label>
-              <div className="text-sm text-gray-900 bg-gray-50 px-3 py-2 rounded-lg border border-gray-200">
-                {getNotificationPersonText()}
-              </div>
-            </div>
-            <div>
-              <label className="block text-sm font-medium text-gray-700 mb-2">
-                通知时间
-              </label>
-              <div className="text-sm text-gray-900 bg-gray-50 px-3 py-2 rounded-lg border border-gray-200">
-                {getNotificationTimeText()}
-              </div>
-            </div>
           </div>
         </div>
       )}
@@ -1872,38 +1861,43 @@ export default function WorkJobDetail() {
     workNode: WorkflowWorkNodeDO | undefined,
     nodeMap: Map<string, WorkflowWorkNodeDO>
   ): 'completed' | 'in_progress' | 'pending' => {
-    if (!approvalStatus || !workNode) return 'pending';
+    if (!workNode) return 'pending';
     
-    // 在字典中查找对应的状态项
-    const statusStr = String(approvalStatus).toLowerCase();
-    const dictItem = approvalStatusDictList.find(item => 
-      String(item.value).toLowerCase() === statusStr || 
-      String(item.label).toLowerCase() === statusStr ||
-      String(item.name).toLowerCase() === statusStr
-    );
+    // 如果没有 approvalStatus,检查父节点状态来决定是否可以执行
+    if (!approvalStatus) {
+      if (!workNode.parentUuid || workNode.parentUuid === '') {
+        return 'pending'; // 没有父节点且没有状态,默认为待执行
+      }
+      // 检查所有父节点是否都已完成
+      const parentUuids = workNode.parentUuid.split(',').map(u => u.trim()).filter(u => u);
+      const allParentsCompleted = parentUuids.every(parentUuid => {
+        const parentNode = nodeMap.get(parentUuid);
+        if (!parentNode) return false;
+        const parentStatus = getNodeStatusFromDict(parentNode.approvalStatus, approvalStatusDictList, parentNode, nodeMap);
+        return parentStatus === 'completed';
+      });
+      return allParentsCompleted ? 'in_progress' : 'pending';
+    }
     
+    // 在字典中查找对应的状态项(优先通过 value 匹配,其次通过 label 匹配)
+    const statusStr = String(approvalStatus).toLowerCase().trim();
+    const dictItem = approvalStatusDictList.find(item => {
+      const itemValue = String(item.value || '').toLowerCase().trim();
+      const itemLabel = String(item.label || '').toLowerCase().trim();
+      return itemValue === statusStr || itemLabel === statusStr;
+    });
+    
+    // 如果找到字典项,根据字典的 value 来映射状态
     if (dictItem) {
-      const label = (dictItem.label || dictItem.name || '').toLowerCase();
+      const dictValue = String(dictItem.value || '').toLowerCase().trim();
       
-      // 根据字典 label 判断状态类型
-      // 已完成、已通过、已审批等 -> completed
-      if (label.includes('已完成') || label.includes('已通过') || label.includes('已审批') || 
-          label.includes('完成') || label.includes('通过') || label.includes('approved')) {
-        return 'completed';
-      }
-      // 进行中、执行中、待审核等 -> in_progress
-      if (label.includes('进行中') || label.includes('执行中') || label.includes('待审核') ||
-          label.includes('pending') || label.includes('running') || label.includes('in_progress')) {
-        return 'in_progress';
-      }
-      // 待执行、未审核、未开始等 -> 需要检查父节点
-      if (label.includes('待执行') || label.includes('未审核') || label.includes('未开始') ||
-          label.includes('待开始') || label.includes('unaudited')) {
-        // 检查父节点状态
+      // 根据字典 value 直接映射状态
+      // pending -> pending (待执行)
+      if (dictValue === 'pending') {
+        // 检查父节点状态,如果所有父节点都已完成,则可以进行中
         if (!workNode.parentUuid || workNode.parentUuid === '') {
-          return 'completed'; // 没有父节点,可能是第一个节点
+          return 'pending';
         }
-        // 检查所有父节点是否都已完成
         const parentUuids = workNode.parentUuid.split(',').map(u => u.trim()).filter(u => u);
         const allParentsCompleted = parentUuids.every(parentUuid => {
           const parentNode = nodeMap.get(parentUuid);
@@ -1913,22 +1907,33 @@ export default function WorkJobDetail() {
         });
         return allParentsCompleted ? 'in_progress' : 'pending';
       }
-      // 已驳回 -> pending
-      if (label.includes('已驳回') || label.includes('rejected')) {
-        return 'pending';
+      // running -> in_progress (进行中)
+      if (dictValue === 'running') {
+        return 'in_progress';
+      }
+      // approved -> completed (已完成)
+      if (dictValue === 'approved') {
+        return 'completed';
+      }
+      // rejected -> completed (已完成,虽然被拒绝但也算完成状态)
+      if (dictValue === 'rejected') {
+        return 'completed';
       }
     }
     
-    // 如果没有找到字典项,使用默认逻辑(兼容旧代码)
+    // 如果没有找到字典项,直接根据 approvalStatus 的值来映射(兼容旧代码)
     if (typeof approvalStatus === 'string') {
       const statusStrLower = approvalStatus.toLowerCase().trim();
       if (statusStrLower === 'approved') {
         return 'completed';
       } else if (statusStrLower === 'running' || statusStrLower === 'in_progress') {
         return 'in_progress';
+      } else if (statusStrLower === 'rejected') {
+        return 'completed'; // rejected 也表示已完成
       } else if (statusStrLower === 'pending' || statusStrLower === 'unaudited') {
+        // 检查父节点状态
         if (!workNode.parentUuid || workNode.parentUuid === '') {
-          return 'completed';
+          return 'pending';
         }
         const parentUuids = workNode.parentUuid.split(',').map(u => u.trim()).filter(u => u);
         const allParentsCompleted = parentUuids.every(parentUuid => {
@@ -1945,8 +1950,9 @@ export default function WorkJobDetail() {
       } else if (approvalStatus === 2) {
         return 'in_progress';
       } else if (approvalStatus === 1) {
+        // 检查父节点状态
         if (!workNode.parentUuid || workNode.parentUuid === '') {
-          return 'completed';
+          return 'pending';
         }
         const parentUuids = workNode.parentUuid.split(',').map(u => u.trim()).filter(u => u);
         const allParentsCompleted = parentUuids.every(parentUuid => {
@@ -1958,6 +1964,7 @@ export default function WorkJobDetail() {
       }
     }
     
+    // 默认返回 pending
     return 'pending';
   };
 
@@ -2029,6 +2036,35 @@ export default function WorkJobDetail() {
         // 节点ID(用于显示):优先从 workNode 获取,如果没有则从 nodeData 获取
         const displayNodeId = workNode?.id ? String(workNode.id) : (nodeData.nodeId || '');
         
+        // 如果是解除隔离节点,需要从对应的隔离方案节点复制数据
+        let isolationNodeData: any = null;
+        if (nodeType === 'releaseIsolation') {
+          // 获取隔离节点UUID(从 workNode 或 nodeData 中获取)
+          const isolationNodeUuid = workNode?.isolationNodeUuid || nodeData.isolationNodeUuid || '';
+          if (isolationNodeUuid) {
+            // 找到对应的隔离方案节点
+            const isolationWorkNode = workflowWorkNodeDOList.find(n => n.uuid === isolationNodeUuid && n.type === 'isolation');
+            if (isolationWorkNode) {
+              // 复制隔离方案节点的数据
+              isolationNodeData = {
+                isolationType: isolationWorkNode.isolationType || '',
+                isolationPoints: isolationWorkNode.isolationPoints 
+                  ? (typeof isolationWorkNode.isolationPoints === 'string' 
+                      ? JSON.parse(isolationWorkNode.isolationPoints) 
+                      : isolationWorkNode.isolationPoints)
+                  : [],
+                lockPerson: isolationWorkNode.nodeUserList?.find((u: any) => u.type === 'locker' || u.type === 'jtlocker')?.userId || '',
+                coLockPersons: isolationWorkNode.nodeUserList?.filter((u: any) => u.type === 'colocker' || u.type === 'jtcolocker').map((u: any) => u.userId) || [],
+                formId: isolationWorkNode.formId || '',
+                workerUserId: isolationWorkNode.workerUserId || '',
+                points: isolationWorkNode.points || [],
+                locks: isolationWorkNode.locks || [],
+              };
+              console.log(`解除隔离节点 ${nodeId} 从隔离方案节点 ${isolationNodeUuid} 复制数据:`, isolationNodeData);
+            }
+          }
+        }
+        
         return {
           id: nodeId,
           type: nodeType, // 使用从 workNode 获取的类型
@@ -2045,6 +2081,8 @@ export default function WorkJobDetail() {
             status: status,
             // 将 workNode 的完整数据也保存到 data 中,方便后续使用
             workNode: workNode,
+            // 如果是解除隔离节点,添加从隔离方案节点复制的数据
+            ...(isolationNodeData ? { isolationNodeData } : {}),
           },
         };
       });
@@ -2523,6 +2561,22 @@ export default function WorkJobDetail() {
     }
     
     let executorName = '';
+    let isolationWorkNode: WorkflowWorkNodeDO | undefined = undefined;
+    
+    // 如果是解除隔离节点且没有执行人,尝试从对应的隔离方案节点获取
+    if (type === 'releaseIsolation' && !workNode.workerUserId && !workNode.workerUserName) {
+      const isolationNodeUuid = workNode.isolationNodeUuid;
+      if (isolationNodeUuid && jobDetail?.workflowWorkNodeDOList) {
+        isolationWorkNode = jobDetail.workflowWorkNodeDOList.find(
+          n => n.uuid === isolationNodeUuid && n.type === 'isolation'
+        );
+        if (isolationWorkNode) {
+          // 使用隔离方案节点的数据
+          workNode = isolationWorkNode;
+        }
+      }
+    }
+    
     if (workNode.nodeUserList && Array.isArray(workNode.nodeUserList)) {
       const workerUser = workNode.nodeUserList.find((user: any) => user.type === 'worker' || !user.type);
       if (workerUser && workerUser.userName) {