qaz il y a 5 jours
Parent
commit
7abea0193a

+ 264 - 81
src/views/system/borrow/approval/SpecialBorrowApp/index.vue

@@ -160,7 +160,7 @@
 		<!-- 审批信息流程展示 -->
 		<div v-if="isView"  style="margin-top: 24px; padding: 0 12px">
 		<div style="font-weight: bold; margin-bottom: 12px">审批流程进度</div>
-		<el-steps :active="steps.length" align-center>
+		<el-steps :active="stepActiveIndex" align-center finish-status="success">
 			<el-step
 				v-for="(step, index) in steps"
 				:key="index"
@@ -453,102 +453,285 @@ const timeline = ref({
 	approvemsg:''
 });
 
+//审批(与 SpecialBorrowApp 同构;通用借用保留仓库等详情)
+// 课堂借用(borrow_type=1)、特殊借用(=2):仅「创建申请 → 审批通过 → 流程完成」,不展示领取仓库
+function formatApprovalRecordTime(t: any): string {
+  if (t == null || t === '') return '';
+  const d = dayjs(t);
+  return d.isValid() ? d.format('YYYY-MM-DD HH:mm:ss') : String(t);
+}
+
+function getApproversTextForNode(step: any): string {
+  if (!step?.approvers?.length) return '';
+  let approvers = step.approvers;
+  const sn = String(step.step_name || '');
+  if (sn.includes('老师')) {
+    approvers = approvers.filter((a: any) => a.type === 'app_user');
+  } else if (sn.includes('管理员')) {
+    approvers = approvers.filter((a: any) => a.type === 'admin');
+  }
+  return approvers
+    .map((a: any) => a.name)
+    .filter((n: string) => n && String(n).trim())
+    .join('、');
+}
+
+/** 领取仓库与选仓操作挂在「管理员」环节;学院领导/老师等节点不展示(与 step_name 约定一致) */
+function isPickupWarehouseStep(workflowStep: any, record: any): boolean {
+  const a = String(workflowStep?.step_name ?? '');
+  const b = String((record as any)?.step_name ?? '');
+  return a.includes('管理员') || b.includes('管理员');
+}
+
+function isAllStepsStatusApprovedStep(step: any): boolean {
+  return (
+    step?.status === 'approved' ||
+    step?.status === 'finished' ||
+    step?.status_label === '已通过' ||
+    step?.status === 'pass'
+  );
+}
+
+function findApprovedRecordForWorkflowStep(
+  step: any,
+  approvedOnly: any[],
+  sortedConfigSteps: any[]
+): any | null {
+  if (!step || !approvedOnly.length) return null;
+  const o = step.step_order;
+  let hit = approvedOnly.find(
+    (r: any) =>
+      r?.step_order != null &&
+      o != null &&
+      Number(r.step_order) === Number(o)
+  );
+  if (hit) return hit;
+  if (step.step_name) {
+    hit = approvedOnly.find(
+      (r: any) =>
+        r?.step_name &&
+        String(r.step_name) === String(step.step_name)
+    );
+    if (hit) return hit;
+  }
+  const stepIdx = sortedConfigSteps.findIndex((s) => s === step);
+  if (stepIdx >= 0 && stepIdx < approvedOnly.length) {
+    const r = approvedOnly[stepIdx];
+    if (r?.status === 1) return r;
+  }
+  return null;
+}
+
+const stepActiveIndex = computed(() => {
+  const s = steps.value;
+  if (!s.length) return 0;
+  const i = s.findIndex((x) => x.status === 'process' || x.status === 'error' || x.status === 'wait');
+  if (i >= 0) return i;
+  return Math.max(0, s.length - 1);
+});
 
 function buildSteps(data: any) {
-  steps.value = [
+  const list: any[] = [
     {
       title: '创建申请',
-      description: `创建时间:${data.create_datetime ? dayjs(data.create_datetime).format('YYYY-MM-DD HH:mm:ss') : ''}`,
-      status: 'finish'
+      description: `创建时间:${
+        data.create_datetime
+          ? dayjs(data.create_datetime).format('YYYY-MM-DD HH:mm:ss')
+          : ''
+      }`,
+      status: 'finish',
     },
-	{
-      title: '待审批',
-      description: `待审批人:${getPendingApproverDisplay(data)} 审批`,
-      status: data.status >= 2 ? 'finish' : 'process'
-    }
   ];
 
-  const approverinfo = data.approver_info ?? data.admin_approver_info
+  if (data.status === 3) {
+    const rejectNames = data.approval_records
+      ?.filter((item: any) => item.status === 2)
+      .map(
+        (item: any) =>
+          item.approver_name || item.app_user_approver_name || item.name
+      )
+      .filter((name: any) => name && name.trim());
+    const rejectReason = data.approval_records
+      ?.filter((item: any) => item.status === 2)
+      .map((item: any) => item.approve_remark)
+      .filter((reason: any) => reason && reason.trim());
+    const rejectTime = data.approval_records
+      ?.filter((item: any) => item.status === 2)
+      .map((item: any) => item.approve_time)
+      .filter((time: any) => time && time.trim());
+    list.push({
+      title: '审批拒绝',
+      description: `审批人:${(rejectNames || []).join('、')},拒绝原因: ${(rejectReason || []).join('、')},时间:${(rejectTime || []).join('、')}`,
+      status: 'error',
+    });
+    steps.value = list;
+    return;
+  }
 
+  const isClassroomOrSpecial =
+    data.borrow_type === 1 || data.borrow_type === 2;
+  if (isClassroomOrSpecial) {
+    if (data.status === 1) {
+      list.push({
+        title: '审批通过',
+        description: `待审批人:${getPendingApproverDisplay(data)} 审批`,
+        status: 'process',
+      });
+    } else if (data.status >= 2) {
+      const approved = (data.approval_records || [])
+        .filter((r: any) => r.status === 1)
+        .sort(
+          (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+        );
+      const last = approved[approved.length - 1];
+      const nameStr = approved.length
+        ? approved
+            .map(
+              (r: any) => r.approver_name || r.app_user_approver_name
+            )
+            .filter((n: string) => n && String(n).trim())
+            .join('、') || '-'
+        : '-';
+      const tRaw = last
+        ? last.approve_time != null
+          ? last.approve_time
+          : last.create_datetime
+        : null;
+      list.push({
+        title: '审批通过',
+        description: `审批人: ${nameStr}, 时间: ${formatApprovalRecordTime(tRaw) || ''}`,
+        status: 'finish',
+      });
+    }
+    if (data.status >= 2 && data.status !== 3) {
+      list.push({
+        title: '流程完成',
+        description: '流程已结束',
+        status: 'finish',
+      });
+    }
+    steps.value = list;
+    return;
+  }
 
-  if (data.status >= 2&&data.status!=3 && data.borrow_type!=1) {
-    /*   // 将审批记录倒序排列
-    const reversedApprovalRecords = [...data.approval_records]
-    reversedApprovalRecords.forEach((item:any,index:number) => {
-      if(item.status === 1){
-        if(index == 1){
-        steps.value.push({
+  const admin = data.admin_approver_info;
+  const allCfg =
+    admin?.all_steps_status && admin.all_steps_status.length
+      ? [...admin.all_steps_status].sort(
+          (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+        )
+      : null;
+
+  if (allCfg) {
+    const approvedOnly = (data.approval_records || [])
+      .filter((r: any) => r.status === 1)
+      .sort(
+        (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+      );
+    const maxPassedOrder = approvedOnly.length
+      ? Math.max(
+          ...approvedOnly.map(
+            (r: any) => (r.step_order != null ? Number(r.step_order) : 0)
+          )
+        )
+      : -1;
+
+    let hasPendingInWorkflow = false;
+    for (const step of allCfg) {
+      const rec = findApprovedRecordForWorkflowStep(
+        step,
+        approvedOnly,
+        allCfg
+      );
+      const done = !!rec || isAllStepsStatusApprovedStep(step);
+      if (done) {
+        const name =
+          (rec as any)?.approver_name ||
+          (rec as any)?.app_user_approver_name ||
+          '';
+        const tRaw =
+          (rec as any)?.approve_time != null
+            ? (rec as any).approve_time
+            : (rec as any)?.create_datetime;
+        const isLastInChain =
+          rec &&
+          (rec as any).step_order != null &&
+          Number((rec as any).step_order) === maxPassedOrder;
+        const warehouseInfo =
+          data.status >= 2 &&
+          data.status !== 3 &&
+          isLastInChain &&
+          isPickupWarehouseStep(step, rec)
+            ? `, 领取仓库:${getWarehouseName(data.warehouse) || '暂无仓库'}`
+            : '';
+        // 与课堂/特殊借用、查看效果图一致:已通过节点统一展示「审批通过」
+        list.push({
           title: '审批通过',
-            description: `审批人:${item.app_user_approver_name},时 间:${item.approve_time}`,
-            status: 'finish'
-          });
-        }else{
-          steps.value.push({
-            title: '审批通过',
-            description: `审批人:${item.approver_name},时 间:${item.create_datetime},领取仓库:${getWarehouseName(data.warehouse)||'暂无仓库'}`,
-            status: 'finish'
-          });
-        }
+          description: `审批人: ${name || '-'}, 时间: ${formatApprovalRecordTime(tRaw) || ''}${warehouseInfo}`,
+          status: 'finish',
+        });
+      } else {
+        hasPendingInWorkflow = true;
+        const names = getApproversTextForNode(step) || getPendingApproverDisplay(data);
+        list.push({
+          title: '待审批',
+          description: `待审批人:${names} 审批`,
+          status: 'process',
+        });
+        break;
       }
-    }); */
-	// 将审批记录倒序排列
-    const reversedApprovalRecords = [...data.approval_records]
-    // 先找出所有审批通过的记录
-    const approvedRecords = reversedApprovalRecords.filter((item:any) => item.status === 1)
-    const lastApprovedIndex = approvedRecords.length - 1
-    
-    reversedApprovalRecords.forEach((item:any,index:number) => {
-      if(item.status === 1){
-        // 找到当前记录在审批通过记录中的索引
-        const currentApprovedIndex = approvedRecords.findIndex((record:any) => record === item)
-        // 判断是否是最后一个审批通过的记录
-        const isLastApproved = currentApprovedIndex === lastApprovedIndex
-        
-       /*  if(index == 1){1
-        steps.value.push({
-          title: '审批通过',
-            description: `审批人:${item.approver_name||item.app_user_approver_name},时 间:${item.approve_time}`,
-            status: 'finish'
-          });
-        }else{ */
-          // 只在最后一个审批通过的记录中显示领取仓库
-          const warehouseInfo = isLastApproved ? `,领取仓库:${getWarehouseName(data.warehouse)||'暂无仓库'}` : ''
-          steps.value.push({
+    }
+    if (
+      !hasPendingInWorkflow &&
+      data.status >= 2 &&
+      data.status !== 3
+    ) {
+      list.push({
+        title: '流程完成',
+        description: '流程已结束',
+        status: 'finish',
+      });
+    }
+  } else {
+    if (data.status === 1) {
+      list.push({
+        title: '待审批',
+        description: `待审批人:${getPendingApproverDisplay(data)} 审批`,
+        status: 'process',
+      });
+    }
+    if (data.status >= 2 && data.status !== 3) {
+      const approvedRecords = (data.approval_records || [])
+        .filter((item: any) => item.status === 1)
+        .sort(
+          (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+        );
+      if (approvedRecords.length > 0) {
+        const lastI = approvedRecords.length - 1;
+        approvedRecords.forEach((item: any, idx: number) => {
+          const isLast = idx === lastI;
+          const wh =
+            isLast && isPickupWarehouseStep(null, item)
+              ? `, 领取仓库:${getWarehouseName(data.warehouse) || '暂无仓库'}`
+              : '';
+          list.push({
             title: '审批通过',
-            description: `审批人:${item.approver_name||item.app_user_approver_name},时 间:${item.create_datetime ? dayjs(item.create_datetime).format('YYYY-MM-DD HH:mm:ss') : ''}${warehouseInfo}`,
-            status: 'finish'
+            description: `审批人: ${item.approver_name || item.app_user_approver_name || '-'}, 时间: ${formatApprovalRecordTime(
+              item.approve_time != null ? item.approve_time : item.create_datetime
+            )}${wh}`,
+            status: 'finish',
           });
-        /* } */
+        });
+        list.push({
+          title: '流程完成',
+          description: '流程已结束',
+          status: 'finish',
+        });
       }
-    });
-  } else if (data.status === 3) {
-    // console.log("data.approver_name:::",data.approver_info.name)
-    const rejectNames = data.approval_records
-      .filter((item:any) => item.status === 2)
-      .map((item:any) => item.approver_name || item.app_user_approver_name || item.name)
-      .filter((name:any) => name && name.trim());
-    const rejectReason = data.approval_records
-      .filter((item:any) => item.status === 2)
-      .map((item:any) => item.approve_remark)
-      .filter((reason:any) => reason && reason.trim());
-    const rejectTime = data.approval_records
-      .filter((item:any) => item.status === 2)
-      .map((item:any) => item.approve_time)
-      .filter((time:any) => time && time.trim());
-    steps.value.push({
-      title: '审批拒绝',
-      description: `审批人:${rejectNames.join('、')},拒绝原因: ${rejectReason.join('、')},时间:${rejectTime.join('、')}`,
-      status: 'error'
-    });
+    }
   }
 
-  if (data.status >= 4) {
-    steps.value.push({
-      title: '流程完成',
-      description: '流程已结束',
-      status: 'finish'
-    });
-  }
+  steps.value = list;
 }
 
 // const activeStep = ref(1);

+ 2 - 2
src/views/system/borrow/approval/curd.tsx

@@ -439,7 +439,7 @@ export const createCrudOptions = function ({ crudExpose ,context, showRejectDial
 				},
 				
 
-				approver_name: {
+				/* approver_name: {
 					title: '当前审批人',	
 					search: { show: true },
 					type: 'input',
@@ -460,7 +460,7 @@ export const createCrudOptions = function ({ crudExpose ,context, showRejectDial
 						component: { placeholder: '请输入审批人' },
 						rules: [{ required: false, message: '' }],
 					},
-				},
+				}, */
 				// 审批流程状态显示
 				/* admin_approver_info: {
 					title: '审批状态',

+ 266 - 64
src/views/system/borrow/component/CollectEquipment/index.vue

@@ -195,7 +195,7 @@
                 </div> -->
                 <div v-if="isView"  style="margin-top: 24px; padding: 0 12px">
                 <div style="font-weight: bold; margin-bottom: 12px">审批流程进度</div>
-                <el-steps :active="steps.length" align-center>
+                <el-steps :active="stepActiveIndex" align-center finish-status="success">
                   <el-step
                     v-for="(step, index) in steps"
                     :key="index"
@@ -1126,83 +1126,285 @@ const currentAbnormalData = ref<AbnormalData>({
   photos: []
 });
 
-//审批
+//审批(与 SpecialBorrowApp 同构;通用借用保留仓库等详情)
+// 课堂借用(borrow_type=1)、特殊借用(=2):仅「创建申请 → 审批通过 → 流程完成」,不展示领取仓库
+function formatApprovalRecordTime(t: any): string {
+  if (t == null || t === '') return '';
+  const d = dayjs(t);
+  return d.isValid() ? d.format('YYYY-MM-DD HH:mm:ss') : String(t);
+}
+
+function getApproversTextForNode(step: any): string {
+  if (!step?.approvers?.length) return '';
+  let approvers = step.approvers;
+  const sn = String(step.step_name || '');
+  if (sn.includes('老师')) {
+    approvers = approvers.filter((a: any) => a.type === 'app_user');
+  } else if (sn.includes('管理员')) {
+    approvers = approvers.filter((a: any) => a.type === 'admin');
+  }
+  return approvers
+    .map((a: any) => a.name)
+    .filter((n: string) => n && String(n).trim())
+    .join('、');
+}
+
+/** 领取仓库与选仓操作挂在「管理员」环节;学院领导/老师等节点不展示(与 step_name 约定一致) */
+function isPickupWarehouseStep(workflowStep: any, record: any): boolean {
+  const a = String(workflowStep?.step_name ?? '');
+  const b = String((record as any)?.step_name ?? '');
+  return a.includes('管理员') || b.includes('管理员');
+}
+
+function isAllStepsStatusApprovedStep(step: any): boolean {
+  return (
+    step?.status === 'approved' ||
+    step?.status === 'finished' ||
+    step?.status_label === '已通过' ||
+    step?.status === 'pass'
+  );
+}
+
+function findApprovedRecordForWorkflowStep(
+  step: any,
+  approvedOnly: any[],
+  sortedConfigSteps: any[]
+): any | null {
+  if (!step || !approvedOnly.length) return null;
+  const o = step.step_order;
+  let hit = approvedOnly.find(
+    (r: any) =>
+      r?.step_order != null &&
+      o != null &&
+      Number(r.step_order) === Number(o)
+  );
+  if (hit) return hit;
+  if (step.step_name) {
+    hit = approvedOnly.find(
+      (r: any) =>
+        r?.step_name &&
+        String(r.step_name) === String(step.step_name)
+    );
+    if (hit) return hit;
+  }
+  const stepIdx = sortedConfigSteps.findIndex((s) => s === step);
+  if (stepIdx >= 0 && stepIdx < approvedOnly.length) {
+    const r = approvedOnly[stepIdx];
+    if (r?.status === 1) return r;
+  }
+  return null;
+}
+
+const stepActiveIndex = computed(() => {
+  const s = steps.value;
+  if (!s.length) return 0;
+  const i = s.findIndex((x) => x.status === 'process' || x.status === 'error' || x.status === 'wait');
+  if (i >= 0) return i;
+  return Math.max(0, s.length - 1);
+});
+
 function buildSteps(data: any) {
-  steps.value = [
+  const list: any[] = [
     {
       title: '创建申请',
-      description: `创建时间:${data.create_datetime ? dayjs(data.create_datetime).format('YYYY-MM-DD HH:mm:ss') : ''}`,
-      status: 'finish'
+      description: `创建时间:${
+        data.create_datetime
+          ? dayjs(data.create_datetime).format('YYYY-MM-DD HH:mm:ss')
+          : ''
+      }`,
+      status: 'finish',
     },
-    {
-      title: '待审批',
-      description: `待审批人:${getPendingApproverDisplay(data)} 审批`,
-      status: data.status >= 2 ? 'finish' : 'process'
-    }
   ];
 
-  const approverinfo = data.approver_info ?? data.admin_approver_info
-
-
-  if (data.status >= 2&&data.status!=3 && data.borrow_type!=1) {
-    // 将审批记录倒序排列
-    const reversedApprovalRecords = [...data.approval_records]
-    // 先找出所有审批通过的记录
-    const approvedRecords = reversedApprovalRecords.filter((item:any) => item.status === 1)
-    const lastApprovedIndex = approvedRecords.length - 1
-    
-    reversedApprovalRecords.forEach((item:any,index:number) => {
-      if(item.status === 1){
-        // 找到当前记录在审批通过记录中的索引
-        const currentApprovedIndex = approvedRecords.findIndex((record:any) => record === item)
-        // 判断是否是最后一个审批通过的记录
-        const isLastApproved = currentApprovedIndex === lastApprovedIndex
-        
-       /*  if(index == 1){1
-        steps.value.push({
-          title: '审批通过',
-            description: `审批人:${item.approver_name||item.app_user_approver_name},时 间:${item.approve_time}`,
-            status: 'finish'
-          });
-        }else{ */
-          // 只在最后一个审批通过的记录中显示领取仓库
-          const warehouseInfo = isLastApproved ? `,领取仓库:${getWarehouseName(data.warehouse)||'暂无仓库'}` : ''
-          steps.value.push({
-            title: '审批通过',
-            description: `审批人:${item.approver_name||item.app_user_approver_name},时 间:${item.create_datetime ? dayjs(item.create_datetime).format('YYYY-MM-DD HH:mm:ss') : ''}${warehouseInfo}`,
-            status: 'finish'
-          });
-        /* } */
-      }
-    });
-  } else if (data.status === 3) {
-    // console.log("data.approver_name:::",data.approver_info.name)
+  if (data.status === 3) {
     const rejectNames = data.approval_records
-      .filter((item:any) => item.status === 2)
-      .map((item:any) => item.approver_name || item.app_user_approver_name || item.name)
-      .filter((name:any) => name && name.trim());
+      ?.filter((item: any) => item.status === 2)
+      .map(
+        (item: any) =>
+          item.approver_name || item.app_user_approver_name || item.name
+      )
+      .filter((name: any) => name && name.trim());
     const rejectReason = data.approval_records
-      .filter((item:any) => item.status === 2)
-      .map((item:any) => item.approve_remark)
-      .filter((reason:any) => reason && reason.trim());
+      ?.filter((item: any) => item.status === 2)
+      .map((item: any) => item.approve_remark)
+      .filter((reason: any) => reason && reason.trim());
     const rejectTime = data.approval_records
-      .filter((item:any) => item.status === 2)
-      .map((item:any) => item.approve_time)
-      .filter((time:any) => time && time.trim());
-    steps.value.push({
+      ?.filter((item: any) => item.status === 2)
+      .map((item: any) => item.approve_time)
+      .filter((time: any) => time && time.trim());
+    list.push({
       title: '审批拒绝',
-      description: `审批人:${rejectNames.join('、')},拒绝原因: ${rejectReason.join('、')},时间:${rejectTime.join('、')}`,
-      status: 'error'
+      description: `审批人:${(rejectNames || []).join('、')},拒绝原因: ${(rejectReason || []).join('、')},时间:${(rejectTime || []).join('、')}`,
+      status: 'error',
     });
+    steps.value = list;
+    return;
   }
 
-  if (data.status >= 4 ||data.borrow_type==1) {
-    steps.value.push({
-      title: '流程完成',
-      description: '流程已结束',
-      status: 'finish'
-    });
+  const isClassroomOrSpecial =
+    data.borrow_type === 1 || data.borrow_type === 2;
+  if (isClassroomOrSpecial) {
+    if (data.status === 1) {
+      list.push({
+        title: '审批通过',
+        description: `待审批人:${getPendingApproverDisplay(data)} 审批`,
+        status: 'process',
+      });
+    } else if (data.status >= 2) {
+      const approved = (data.approval_records || [])
+        .filter((r: any) => r.status === 1)
+        .sort(
+          (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+        );
+      const last = approved[approved.length - 1];
+      const nameStr = approved.length
+        ? approved
+            .map(
+              (r: any) => r.approver_name || r.app_user_approver_name
+            )
+            .filter((n: string) => n && String(n).trim())
+            .join('、') || '-'
+        : '-';
+      const tRaw = last
+        ? last.approve_time != null
+          ? last.approve_time
+          : last.create_datetime
+        : null;
+      list.push({
+        title: '审批通过',
+        description: `审批人: ${nameStr}, 时间: ${formatApprovalRecordTime(tRaw) || ''}`,
+        status: 'finish',
+      });
+    }
+    if (data.status >= 2 && data.status !== 3) {
+      list.push({
+        title: '流程完成',
+        description: '流程已结束',
+        status: 'finish',
+      });
+    }
+    steps.value = list;
+    return;
+  }
+
+  const admin = data.admin_approver_info;
+  const allCfg =
+    admin?.all_steps_status && admin.all_steps_status.length
+      ? [...admin.all_steps_status].sort(
+          (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+        )
+      : null;
+
+  if (allCfg) {
+    const approvedOnly = (data.approval_records || [])
+      .filter((r: any) => r.status === 1)
+      .sort(
+        (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+      );
+    const maxPassedOrder = approvedOnly.length
+      ? Math.max(
+          ...approvedOnly.map(
+            (r: any) => (r.step_order != null ? Number(r.step_order) : 0)
+          )
+        )
+      : -1;
+
+    let hasPendingInWorkflow = false;
+    for (const step of allCfg) {
+      const rec = findApprovedRecordForWorkflowStep(
+        step,
+        approvedOnly,
+        allCfg
+      );
+      const done = !!rec || isAllStepsStatusApprovedStep(step);
+      if (done) {
+        const name =
+          (rec as any)?.approver_name ||
+          (rec as any)?.app_user_approver_name ||
+          '';
+        const tRaw =
+          (rec as any)?.approve_time != null
+            ? (rec as any).approve_time
+            : (rec as any)?.create_datetime;
+        const isLastInChain =
+          rec &&
+          (rec as any).step_order != null &&
+          Number((rec as any).step_order) === maxPassedOrder;
+        const warehouseInfo =
+          data.status >= 2 &&
+          data.status !== 3 &&
+          isLastInChain &&
+          isPickupWarehouseStep(step, rec)
+            ? `, 领取仓库:${getWarehouseName(data.warehouse) || '暂无仓库'}`
+            : '';
+        // 与课堂/特殊借用、查看效果图一致:已通过节点统一展示「审批通过」
+        list.push({
+          title: '审批通过',
+          description: `审批人: ${name || '-'}, 时间: ${formatApprovalRecordTime(tRaw) || ''}${warehouseInfo}`,
+          status: 'finish',
+        });
+      } else {
+        hasPendingInWorkflow = true;
+        const names = getApproversTextForNode(step) || getPendingApproverDisplay(data);
+        list.push({
+          title: '待审批',
+          description: `待审批人:${names} 审批`,
+          status: 'process',
+        });
+        break;
+      }
+    }
+    if (
+      !hasPendingInWorkflow &&
+      data.status >= 2 &&
+      data.status !== 3
+    ) {
+      list.push({
+        title: '流程完成',
+        description: '流程已结束',
+        status: 'finish',
+      });
+    }
+  } else {
+    if (data.status === 1) {
+      list.push({
+        title: '待审批',
+        description: `待审批人:${getPendingApproverDisplay(data)} 审批`,
+        status: 'process',
+      });
+    }
+    if (data.status >= 2 && data.status !== 3) {
+      const approvedRecords = (data.approval_records || [])
+        .filter((item: any) => item.status === 1)
+        .sort(
+          (a: any, b: any) => (a.step_order ?? 0) - (b.step_order ?? 0)
+        );
+      if (approvedRecords.length > 0) {
+        const lastI = approvedRecords.length - 1;
+        approvedRecords.forEach((item: any, idx: number) => {
+          const isLast = idx === lastI;
+          const wh =
+            isLast && isPickupWarehouseStep(null, item)
+              ? `, 领取仓库:${getWarehouseName(data.warehouse) || '暂无仓库'}`
+              : '';
+          list.push({
+            title: '审批通过',
+            description: `审批人: ${item.approver_name || item.app_user_approver_name || '-'}, 时间: ${formatApprovalRecordTime(
+              item.approve_time != null ? item.approve_time : item.create_datetime
+            )}${wh}`,
+            status: 'finish',
+          });
+        });
+        list.push({
+          title: '流程完成',
+          description: '流程已结束',
+          status: 'finish',
+        });
+      }
+    }
   }
+
+  steps.value = list;
 }
 
 // 处理异常操作(按 device_no 定位,避免与「按时间排序的表格」下标错位)