liuhairui 2 tuần trước cách đây
mục cha
commit
17d84d2090

+ 172 - 101
application/admin/controller/Procuremen.php

@@ -4,6 +4,7 @@ namespace app\admin\controller;
 
 
 use app\common\controller\Backend;
 use app\common\controller\Backend;
 use app\common\library\AliyunOss;
 use app\common\library\AliyunOss;
+use app\common\library\ProcuremenStatus;
 use PHPMailer\PHPMailer\PHPMailer;
 use PHPMailer\PHPMailer\PHPMailer;
 use think\Config;
 use think\Config;
 use PhpOffice\PhpSpreadsheet\Spreadsheet;
 use PhpOffice\PhpSpreadsheet\Spreadsheet;
@@ -413,12 +414,13 @@ class Procuremen extends Backend
             $query = Db::table('purchase_order');
             $query = Db::table('purchase_order');
             $this->applyPurchaseOrderNotDeletedWhere($query);
             $this->applyPurchaseOrderNotDeletedWhere($query);
             if ($stage === 'audit') {
             if ($stage === 'audit') {
-                $query->whereIn('wflow_status', [1, '1']);
+                $query->whereIn('wflow_status', ProcuremenStatus::wflowPendingConfirmValues());
             } elseif ($stage === 'confirm') {
             } elseif ($stage === 'confirm') {
-                $query->where('status', 0)->where(function ($q) {
-                    $q->where('wflow_status', 2)
+                $query->whereRaw(ProcuremenStatus::sqlPoInProgress('status'))->where(function ($q) {
+                    $q->whereIn('wflow_status', ProcuremenStatus::wflowPendingApprovalValues())
                         ->whereOr(function ($q2) {
                         ->whereOr(function ($q2) {
-                            $q2->where('wflow_status', 0)->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
+                            $q2->whereIn('wflow_status', ProcuremenStatus::wflowPendingIssueValues())
+                                ->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
                         });
                         });
                 });
                 });
             } else {
             } else {
@@ -461,12 +463,13 @@ class Procuremen extends Backend
             $query = Db::table('purchase_order');
             $query = Db::table('purchase_order');
             $this->applyPurchaseOrderNotDeletedWhere($query);
             $this->applyPurchaseOrderNotDeletedWhere($query);
             if ($stage === 'audit') {
             if ($stage === 'audit') {
-                $query->whereIn('wflow_status', [1, '1']);
+                $query->whereIn('wflow_status', ProcuremenStatus::wflowPendingConfirmValues());
             } elseif ($stage === 'confirm') {
             } elseif ($stage === 'confirm') {
-                $query->where('status', 0)->where(function ($q) {
-                    $q->where('wflow_status', 2)
+                $query->whereRaw(ProcuremenStatus::sqlPoInProgress('status'))->where(function ($q) {
+                    $q->whereIn('wflow_status', ProcuremenStatus::wflowPendingApprovalValues())
                         ->whereOr(function ($q2) {
                         ->whereOr(function ($q2) {
-                            $q2->where('wflow_status', 0)->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
+                            $q2->whereIn('wflow_status', ProcuremenStatus::wflowPendingIssueValues())
+                                ->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
                         });
                         });
                 });
                 });
             } else {
             } else {
@@ -493,16 +496,16 @@ class Procuremen extends Backend
         );
         );
     }
     }
 
 
-    /** purchase_order_detail.status:2=废弃归档(保留留痕,不参与当前流程) */
-    protected const PURCHASE_DETAIL_STATUS_VOID = 2;
+    /** @deprecated 使用 {@see ProcuremenStatus::POD_VOID} */
+    protected const PURCHASE_DETAIL_STATUS_VOID = '已废弃';
 
 
     protected function isPurchaseOrderDetailVoid(array $row): bool
     protected function isPurchaseOrderDetailVoid(array $row): bool
     {
     {
-        if ((int)($row['status'] ?? 0) === self::PURCHASE_DETAIL_STATUS_VOID) {
+        if (ProcuremenStatus::isPodVoid($row['status'] ?? '')) {
             return true;
             return true;
         }
         }
 
 
-        return trim((string)($row['status_name'] ?? '')) === '已废弃';
+        return trim((string)($row['status_name'] ?? '')) === ProcuremenStatus::POD_VOID;
     }
     }
 
 
     /**
     /**
@@ -510,9 +513,8 @@ class Procuremen extends Backend
      */
      */
     protected function applyActivePurchaseOrderDetailWhere($query): void
     protected function applyActivePurchaseOrderDetailWhere($query): void
     {
     {
-        $void = self::PURCHASE_DETAIL_STATUS_VOID;
-        $query->whereRaw('(`status` IS NULL OR `status` <> ' . $void . ')')
-            ->whereRaw('(status_name IS NULL OR TRIM(status_name) = \'\' OR status_name <> \'已废弃\')');
+        $query->whereRaw(ProcuremenStatus::sqlPodNotVoid('status'))
+            ->whereRaw('(status_name IS NULL OR TRIM(status_name) = \'\' OR status_name <> \'' . ProcuremenStatus::POD_VOID . '\')');
     }
     }
 
 
     /**
     /**
@@ -520,12 +522,12 @@ class Procuremen extends Backend
      */
      */
     protected function purchaseOrderDetailActiveExistsSql(string $detailAlias = 'd'): string
     protected function purchaseOrderDetailActiveExistsSql(string $detailAlias = 'd'): string
     {
     {
-        $void = self::PURCHASE_DETAIL_STATUS_VOID;
+        $void = ProcuremenStatus::POD_VOID;
 
 
         return 'EXISTS (SELECT 1 FROM purchase_order_detail ' . $detailAlias
         return 'EXISTS (SELECT 1 FROM purchase_order_detail ' . $detailAlias
             . ' WHERE ' . $detailAlias . '.scydgy_id = purchase_order.scydgy_id'
             . ' WHERE ' . $detailAlias . '.scydgy_id = purchase_order.scydgy_id'
-            . ' AND (' . $detailAlias . '.`status` IS NULL OR ' . $detailAlias . '.`status` <> ' . $void . ')'
-            . ' AND (' . $detailAlias . '.status_name IS NULL OR TRIM(' . $detailAlias . '.status_name) = \'\' OR ' . $detailAlias . '.status_name <> \'已废弃\')'
+            . ' AND ' . str_replace('`status`', $detailAlias . '.`status`', ProcuremenStatus::sqlPodNotVoid($detailAlias . '.status'))
+            . ' AND (' . $detailAlias . '.status_name IS NULL OR TRIM(' . $detailAlias . '.status_name) = \'\' OR ' . $detailAlias . '.status_name <> \'' . $void . '\')'
             . ' LIMIT 1)';
             . ' LIMIT 1)';
     }
     }
 
 
@@ -546,14 +548,14 @@ class Procuremen extends Backend
         if ($ids === []) {
         if ($ids === []) {
             return;
             return;
         }
         }
-        $void = self::PURCHASE_DETAIL_STATUS_VOID;
+        $void = ProcuremenStatus::POD_VOID;
         Db::table('purchase_order_detail')
         Db::table('purchase_order_detail')
             ->where('scydgy_id', 'in', array_keys($ids))
             ->where('scydgy_id', 'in', array_keys($ids))
-            ->whereRaw('(`status` IS NULL OR `status` <> ' . $void . ')')
-            ->whereRaw('(status_name IS NULL OR TRIM(status_name) = \'\' OR status_name <> \'已废弃\')')
+            ->whereRaw(ProcuremenStatus::sqlPodNotVoid('status'))
+            ->whereRaw('(status_name IS NULL OR TRIM(status_name) = \'\' OR status_name <> \'' . $void . '\')')
             ->update([
             ->update([
                 'status'      => $void,
                 'status'      => $void,
-                'status_name' => '已废弃',
+                'status_name' => $void,
             ]);
             ]);
     }
     }
 
 
@@ -596,12 +598,13 @@ class Procuremen extends Backend
             $query = Db::table('purchase_order')->field($fields);
             $query = Db::table('purchase_order')->field($fields);
             $this->applyPurchaseOrderNotDeletedWhere($query);
             $this->applyPurchaseOrderNotDeletedWhere($query);
             if ($stage === 'audit') {
             if ($stage === 'audit') {
-                $query->whereIn('wflow_status', [1, '1'])->order('pick_time', 'desc')->order('id', 'desc');
+                $query->whereIn('wflow_status', ProcuremenStatus::wflowPendingConfirmValues())->order('pick_time', 'desc')->order('id', 'desc');
             } elseif ($stage === 'confirm') {
             } elseif ($stage === 'confirm') {
-                $query->where('status', 0)->where(function ($q) {
-                    $q->where('wflow_status', 2)
+                $query->whereRaw(ProcuremenStatus::sqlPoInProgress('status'))->where(function ($q) {
+                    $q->whereIn('wflow_status', ProcuremenStatus::wflowPendingApprovalValues())
                         ->whereOr(function ($q2) {
                         ->whereOr(function ($q2) {
-                            $q2->where('wflow_status', 0)->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
+                            $q2->whereIn('wflow_status', ProcuremenStatus::wflowPendingIssueValues())
+                                ->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
                         });
                         });
                 })->order('pick_time', 'desc')->order('id', 'desc');
                 })->order('pick_time', 'desc')->order('id', 'desc');
             } else {
             } else {
@@ -1078,7 +1081,10 @@ class Procuremen extends Backend
         $issuedSet = [];
         $issuedSet = [];
         try {
         try {
             $poList = Db::table('purchase_order')
             $poList = Db::table('purchase_order')
-                ->whereRaw('(`status` = 0 OR `status` = 1)')
+                ->whereIn('status', array_merge(
+                    ProcuremenStatus::poInProgressValues(),
+                    ProcuremenStatus::poCompletedValues()
+                ))
                 ->column('scydgy_id');
                 ->column('scydgy_id');
             if (is_array($poList)) {
             if (is_array($poList)) {
                 foreach ($poList as $ids) {
                 foreach ($poList as $ids) {
@@ -1122,8 +1128,13 @@ class Procuremen extends Backend
         try {
         try {
             $poIds = Db::table('purchase_order')
             $poIds = Db::table('purchase_order')
                 ->where(function ($q) {
                 ->where(function ($q) {
-                    $q->where('wflow_status', '>=', 1)
-                        ->whereOr('status', 1)
+                    $q->whereIn('wflow_status', array_merge(
+                        ProcuremenStatus::wflowPendingConfirmValues(),
+                        ProcuremenStatus::wflowPendingApprovalValues()
+                    ))
+                        ->whereOr(function ($q1) {
+                            $q1->whereIn('status', ProcuremenStatus::poCompletedValues());
+                        })
                         ->whereOr(function ($q2) {
                         ->whereOr(function ($q2) {
                             $q2->whereNotNull('pick_time')
                             $q2->whereNotNull('pick_time')
                                 ->where('pick_time', '<>', '')
                                 ->where('pick_time', '<>', '')
@@ -1223,12 +1234,12 @@ class Procuremen extends Backend
             if ($sid >= 0) {
             if ($sid >= 0) {
                 continue;
                 continue;
             }
             }
-            $wf = (int)($dbRow['wflow_status'] ?? 0);
-            if ($wf >= 1) {
+            $wf = ProcuremenStatus::normalizeWflowStatus($dbRow['wflow_status'] ?? '');
+            if (ProcuremenStatus::wflowAtLeastConfirm($dbRow['wflow_status'] ?? '')) {
                 continue;
                 continue;
             }
             }
-            $st = trim((string)($dbRow['status'] ?? ''));
-            if ($st === '1' || $st === '0') {
+            $st = ProcuremenStatus::normalizePoStatus($dbRow['status'] ?? '');
+            if ($st === ProcuremenStatus::PO_COMPLETED || $st === ProcuremenStatus::PO_IN_PROGRESS) {
                 continue;
                 continue;
             }
             }
             if (isset($detailSidSet[$sid])) {
             if (isset($detailSidSet[$sid])) {
@@ -1355,7 +1366,7 @@ class Procuremen extends Backend
             try {
             try {
                 $po = Db::table('purchase_order')->where('scydgy_id', $sid)->find();
                 $po = Db::table('purchase_order')->where('scydgy_id', $sid)->find();
                 if (is_array($po)) {
                 if (is_array($po)) {
-                    if ((int)($po['wflow_status'] ?? 0) >= 1) {
+                    if (ProcuremenStatus::wflowAtLeastConfirm($po['wflow_status'] ?? '')) {
                         throw new \InvalidArgumentException('手工新增工序已下发,无法删除');
                         throw new \InvalidArgumentException('手工新增工序已下发,无法删除');
                     }
                     }
                     if ($this->isPurchaseOrderSoftDeleted($po['mod_rq'] ?? null)) {
                     if ($this->isPurchaseOrderSoftDeleted($po['mod_rq'] ?? null)) {
@@ -1420,7 +1431,7 @@ class Procuremen extends Backend
             'cywyxm'        => trim((string)($params['cywyxm'] ?? '')),
             'cywyxm'        => trim((string)($params['cywyxm'] ?? '')),
             'This_quantity' => trim((string)($params['This_quantity'] ?? '')),
             'This_quantity' => trim((string)($params['This_quantity'] ?? '')),
             'ceilingPrice'  => trim((string)($params['ceilingPrice'] ?? '')),
             'ceilingPrice'  => trim((string)($params['ceilingPrice'] ?? '')),
-            'wflow_status'  => 0,
+            'wflow_status'  => ProcuremenStatus::WFLOW_PENDING_ISSUE,
             'createtime'    => $now,
             'createtime'    => $now,
             'dStamp'        => $now,
             'dStamp'        => $now,
             'dputrecord'    => $now,
             'dputrecord'    => $now,
@@ -1477,7 +1488,7 @@ class Procuremen extends Backend
     {
     {
         $set = [];
         $set = [];
         try {
         try {
-            $rows = Db::table('purchase_order_detail')->where('status', 1)->field('scydgy_id')->select();
+            $rows = Db::table('purchase_order_detail')->whereIn('status', ProcuremenStatus::podPickedValues())->field('scydgy_id')->select();
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
             $rows = [];
             $rows = [];
         }
         }
@@ -1513,7 +1524,7 @@ class Procuremen extends Backend
         try {
         try {
             $rows = Db::table('purchase_order_detail')
             $rows = Db::table('purchase_order_detail')
                 ->where('scydgy_id', 'in', $scydgyIds)
                 ->where('scydgy_id', 'in', $scydgyIds)
-                ->where('status', 1)
+                ->whereIn('status', ProcuremenStatus::podPickedValues())
                 ->field('scydgy_id,company_name')
                 ->field('scydgy_id,company_name')
                 ->order('id', 'asc')
                 ->order('id', 'asc')
                 ->select();
                 ->select();
@@ -1521,7 +1532,7 @@ class Procuremen extends Backend
             try {
             try {
                 $rows = Db::table('purchase_order_detail')
                 $rows = Db::table('purchase_order_detail')
                     ->where('scydgy_id', 'in', $scydgyIds)
                     ->where('scydgy_id', 'in', $scydgyIds)
-                    ->where('status', 1)
+                    ->whereIn('status', ProcuremenStatus::podPickedValues())
                     ->field('scydgy_id,company_name')
                     ->field('scydgy_id,company_name')
                     ->order('ID', 'asc')
                     ->order('ID', 'asc')
                     ->select();
                     ->select();
@@ -2602,7 +2613,7 @@ class Procuremen extends Backend
 
 
             if ($asComplete) {
             if ($asComplete) {
                 // 主表 status 为 varchar 时统一写 '1',档案 procuremenarchive 按 status=1 查询
                 // 主表 status 为 varchar 时统一写 '1',档案 procuremenarchive 按 status=1 查询
-                $data['status'] = '1';
+                $data['status'] = ProcuremenStatus::PO_COMPLETED;
             }
             }
 
 
             $qtyCd = trim((string)($data['This_quantity'] ?? ''));
             $qtyCd = trim((string)($data['This_quantity'] ?? ''));
@@ -2886,12 +2897,12 @@ class Procuremen extends Backend
             Db::startTrans();
             Db::startTrans();
         }
         }
         try {
         try {
-            Db::table('purchase_order_detail')->where('scydgy_id', $sid)->update(['status' => 0]);
+            Db::table('purchase_order_detail')->where('scydgy_id', $sid)->update(['status' => ProcuremenStatus::POD_UNPICKED]);
             $aff = 0;
             $aff = 0;
             try {
             try {
-                $aff = (int)Db::table('purchase_order_detail')->where('scydgy_id', $sid)->where('id', 'in', $selectedIds)->update(['status' => 1]);
+                $aff = (int)Db::table('purchase_order_detail')->where('scydgy_id', $sid)->where('id', 'in', $selectedIds)->update(['status' => ProcuremenStatus::POD_PICKED]);
             } catch (\Throwable $e) {
             } catch (\Throwable $e) {
-                $aff = (int)Db::table('purchase_order_detail')->where('scydgy_id', $sid)->where('ID', 'in', $selectedIds)->update(['status' => 1]);
+                $aff = (int)Db::table('purchase_order_detail')->where('scydgy_id', $sid)->where('ID', 'in', $selectedIds)->update(['status' => ProcuremenStatus::POD_PICKED]);
             }
             }
             if ($aff < 1) {
             if ($aff < 1) {
                 throw new \Exception('更新选中状态失败');
                 throw new \Exception('更新选中状态失败');
@@ -2901,12 +2912,12 @@ class Procuremen extends Backend
                 $poAff = (int)Db::table('purchase_order')
                 $poAff = (int)Db::table('purchase_order')
                     ->where('id', $purchaseOrderId)
                     ->where('id', $purchaseOrderId)
                     ->where('scydgy_id', $sid)
                     ->where('scydgy_id', $sid)
-                    ->update(['status' => 1]);
+                    ->update(['status' => ProcuremenStatus::POD_PICKED]);
                 if ($poAff < 1) {
                 if ($poAff < 1) {
                     throw new \Exception('主表订单不存在或与工序行不匹配');
                     throw new \Exception('主表订单不存在或与工序行不匹配');
                 }
                 }
             } else {
             } else {
-                $poAff = (int)Db::table('purchase_order')->where('scydgy_id', $sid)->update(['status' => '1']);
+                $poAff = (int)Db::table('purchase_order')->where('scydgy_id', $sid)->update(['status' => ProcuremenStatus::PO_COMPLETED]);
                 if ($poAff < 1) {
                 if ($poAff < 1) {
                     throw new \Exception('未找到');
                     throw new \Exception('未找到');
                 }
                 }
@@ -3292,8 +3303,7 @@ class Procuremen extends Backend
         if ($detailCount > 0) {
         if ($detailCount > 0) {
             return true;
             return true;
         }
         }
-        $wf = (int)($main['wflow_status'] ?? 0);
-        if ($wf >= 1) {
+        if (ProcuremenStatus::wflowAtLeastConfirm($main['wflow_status'] ?? '')) {
             return true;
             return true;
         }
         }
         $pickTime = trim((string)($main['pick_time'] ?? ''));
         $pickTime = trim((string)($main['pick_time'] ?? ''));
@@ -3408,7 +3418,7 @@ class Procuremen extends Backend
             if ($this->detailRowSupplierAccepted($dr)) {
             if ($this->detailRowSupplierAccepted($dr)) {
                 $acceptCnt++;
                 $acceptCnt++;
             }
             }
-            if ((int)($dr['status'] ?? 0) === 1) {
+            if (ProcuremenStatus::isPodPicked($dr['status'] ?? '')) {
                 if ($pickedName === '') {
                 if ($pickedName === '') {
                     $pickedName = trim((string)($dr['company_name'] ?? ''));
                     $pickedName = trim((string)($dr['company_name'] ?? ''));
                 }
                 }
@@ -3426,8 +3436,9 @@ class Procuremen extends Backend
         if ($poTime === '') {
         if ($poTime === '') {
             $poTime = $this->formatProcuremenDetailTime($main['dStamp'] ?? null);
             $poTime = $this->formatProcuremenDetailTime($main['dStamp'] ?? null);
         }
         }
-        $mainStatus = isset($main['status']) ? (int)$main['status'] : 0;
-        $wflowStatus = (int)($main['wflow_status'] ?? 0);
+        $mainCompleted = ProcuremenStatus::isPoCompleted($main['status'] ?? '');
+        $wflowPendingApproval = ProcuremenStatus::isWflowPendingApproval($main['wflow_status'] ?? '');
+        $wflowAtLeastConfirm = ProcuremenStatus::wflowAtLeastConfirm($main['wflow_status'] ?? '');
         $issued = $this->isProcuremenOrderIssued($main, $issueCnt);
         $issued = $this->isProcuremenOrderIssued($main, $issueCnt);
         $issueTime = $issued ? $this->resolveProcuremenIssueTime($main, $details) : '';
         $issueTime = $issued ? $this->resolveProcuremenIssueTime($main, $details) : '';
 
 
@@ -3448,10 +3459,10 @@ class Procuremen extends Backend
             }
             }
         }
         }
 
 
-        $directComplete = ($mainStatus === 1 && !$issued);
+        $directComplete = ($mainCompleted && !$issued);
 
 
         $doneTime = '';
         $doneTime = '';
-        if ($mainStatus === 1) {
+        if ($mainCompleted) {
             if ($directComplete) {
             if ($directComplete) {
                 $doneTime = $this->resolveProcuremenMarkCompleteTime($scydgyId);
                 $doneTime = $this->resolveProcuremenMarkCompleteTime($scydgyId);
             }
             }
@@ -3472,6 +3483,9 @@ class Procuremen extends Backend
             if ($doneTime === '') {
             if ($doneTime === '') {
                 $doneTime = $poTime;
                 $doneTime = $poTime;
             }
             }
+            if ($confirmApproveTime !== '') {
+                $doneTime = $confirmApproveTime;
+            }
         }
         }
 
 
         if ($directComplete) {
         if ($directComplete) {
@@ -3486,20 +3500,20 @@ class Procuremen extends Backend
             $step1Done = $issued;
             $step1Done = $issued;
             $step2Done = $issued;
             $step2Done = $issued;
             $step3Done = $acceptCnt > 0;
             $step3Done = $acceptCnt > 0;
-            $step4Done = $wflowStatus >= 2;
+            $step4Done = $wflowPendingApproval;
             if (!$step4Done) {
             if (!$step4Done) {
                 foreach ($details as $dr) {
                 foreach ($details as $dr) {
-                    if (is_array($dr) && (int)($dr['status'] ?? 0) === 1) {
+                    if (is_array($dr) && ProcuremenStatus::isPodPicked($dr['status'] ?? '')) {
                         $step4Done = true;
                         $step4Done = true;
                         break;
                         break;
                     }
                     }
                 }
                 }
             }
             }
-            $step5Done = $confirmApproveTime !== '' || $mainStatus === 1;
-            $step6Done = $mainStatus === 1;
+            $step5Done = $confirmApproveTime !== '' || $mainCompleted;
+            $step6Done = $mainCompleted;
 
 
             // 已走下发流程并完结:中间环节按业务视为已全部完成(不显示灰色「未到达」)
             // 已走下发流程并完结:中间环节按业务视为已全部完成(不显示灰色「未到达」)
-            if ($mainStatus === 1 && $issued) {
+            if ($mainCompleted && $issued) {
                 $step3Done = true;
                 $step3Done = true;
                 $step4Done = true;
                 $step4Done = true;
                 $step5Done = true;
                 $step5Done = true;
@@ -3710,6 +3724,7 @@ class Procuremen extends Backend
             }
             }
             $r['delivery_ymd'] = $this->formatDeliveryYmd($r['delivery'] ?? null);
             $r['delivery_ymd'] = $this->formatDeliveryYmd($r['delivery'] ?? null);
             $r['is_void'] = is_array($r) && $this->isPurchaseOrderDetailVoid($r);
             $r['is_void'] = is_array($r) && $this->isPurchaseOrderDetailVoid($r);
+            $r['is_picked'] = is_array($r) && ProcuremenStatus::isPodPicked($r['status'] ?? '');
             $r['oper_time_text'] = $this->resolveDetailSupplierOperTime($r);
             $r['oper_time_text'] = $this->resolveDetailSupplierOperTime($r);
         }
         }
         unset($r);
         unset($r);
@@ -3894,14 +3909,12 @@ class Procuremen extends Backend
             if (!is_array($po)) {
             if (!is_array($po)) {
                 continue;
                 continue;
             }
             }
-            $wf = (int)($po['wflow_status'] ?? 0);
-            $st = $po['status'] ?? null;
-            if ($wf >= 1 || $st === 1 || $st === '1') {
+            if (ProcuremenStatus::wflowAtLeastConfirm($po['wflow_status'] ?? '') || ProcuremenStatus::isPoCompleted($po['status'] ?? '')) {
                 $gymc = trim((string)($r['CGYMC'] ?? ''));
                 $gymc = trim((string)($r['CGYMC'] ?? ''));
                 $this->error('工序「' . ($gymc !== '' ? $gymc : ('#' . $id)) . '」已进入审批流程,不能重复下发');
                 $this->error('工序「' . ($gymc !== '' ? $gymc : ('#' . $id)) . '」已进入审批流程,不能重复下发');
             }
             }
             $detCnt = (int)($detCntBySid[$id] ?? 0);
             $detCnt = (int)($detCntBySid[$id] ?? 0);
-            if ($detCnt > 0 && $wf < 1) {
+            if ($detCnt > 0 && !ProcuremenStatus::wflowAtLeastConfirm($po['wflow_status'] ?? '')) {
                 $gymc = trim((string)($r['CGYMC'] ?? ''));
                 $gymc = trim((string)($r['CGYMC'] ?? ''));
                 $this->error('工序「' . ($gymc !== '' ? $gymc : ('#' . $id)) . '」已存在下发明细,请走采购确认或联系管理员');
                 $this->error('工序「' . ($gymc !== '' ? $gymc : ('#' . $id)) . '」已存在下发明细,请走采购确认或联系管理员');
             }
             }
@@ -4040,7 +4053,7 @@ class Procuremen extends Backend
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
             $anchor = null;
             $anchor = null;
         }
         }
-        if (!is_array($anchor) || (int)($anchor['wflow_status'] ?? 0) !== 1) {
+        if (!is_array($anchor) || !ProcuremenStatus::isWflowPendingConfirm($anchor['wflow_status'] ?? '')) {
             return $empty;
             return $empty;
         }
         }
         $ccydh = trim((string)($anchor['CCYDH'] ?? ''));
         $ccydh = trim((string)($anchor['CCYDH'] ?? ''));
@@ -4048,7 +4061,7 @@ class Procuremen extends Backend
             return ['ccydh' => '', 'pos' => [$anchor], 'merge_rows' => $this->scydgyRowsForPurchaseOrders([$anchor])];
             return ['ccydh' => '', 'pos' => [$anchor], 'merge_rows' => $this->scydgyRowsForPurchaseOrders([$anchor])];
         }
         }
         try {
         try {
-            $pos = Db::table('purchase_order')->where('CCYDH', $ccydh)->where('wflow_status', 1)->order('scydgy_id', 'asc')->select();
+            $pos = Db::table('purchase_order')->where('CCYDH', $ccydh)->whereIn('wflow_status', ProcuremenStatus::wflowPendingConfirmValues())->order('scydgy_id', 'asc')->select();
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
             $pos = [$anchor];
             $pos = [$anchor];
         }
         }
@@ -4068,15 +4081,13 @@ class Procuremen extends Backend
      */
      */
     protected function purchaseOrderRowInConfirmStage(array $po): bool
     protected function purchaseOrderRowInConfirmStage(array $po): bool
     {
     {
-        $st = $po['status'] ?? null;
-        if ($st === 1 || $st === '1') {
+        if (ProcuremenStatus::isPoCompleted($po['status'] ?? '')) {
             return false;
             return false;
         }
         }
-        $wf = (int)($po['wflow_status'] ?? 0);
-        if ($wf === 2) {
+        if (ProcuremenStatus::isWflowPendingApproval($po['wflow_status'] ?? '')) {
             return true;
             return true;
         }
         }
-        if ($wf === 0) {
+        if (ProcuremenStatus::isWflowPendingIssue($po['wflow_status'] ?? '')) {
             $sid = (int)($po['scydgy_id'] ?? 0);
             $sid = (int)($po['scydgy_id'] ?? 0);
 
 
             return $this->isValidScydgyRowId($sid) && $this->purchaseOrderDetail($sid) !== [];
             return $this->isValidScydgyRowId($sid) && $this->purchaseOrderDetail($sid) !== [];
@@ -4116,11 +4127,12 @@ class Procuremen extends Backend
         try {
         try {
             $pos = Db::table('purchase_order')
             $pos = Db::table('purchase_order')
                 ->where('CCYDH', $ccydh)
                 ->where('CCYDH', $ccydh)
-                ->where('status', 0)
+                ->whereRaw(ProcuremenStatus::sqlPoInProgress('status'))
                 ->where(function ($q) {
                 ->where(function ($q) {
-                    $q->where('wflow_status', 2)
+                    $q->whereIn('wflow_status', ProcuremenStatus::wflowPendingApprovalValues())
                         ->whereOr(function ($q2) {
                         ->whereOr(function ($q2) {
-                            $q2->where('wflow_status', 0)->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
+                            $q2->whereIn('wflow_status', ProcuremenStatus::wflowPendingIssueValues())
+                                ->whereRaw($this->purchaseOrderDetailActiveExistsSql('d'));
                         });
                         });
                 })
                 })
                 ->order('scydgy_id', 'asc')
                 ->order('scydgy_id', 'asc')
@@ -4359,7 +4371,7 @@ class Procuremen extends Backend
             if (!is_array($d)) {
             if (!is_array($d)) {
                 continue;
                 continue;
             }
             }
-            if (!$this->isPurchaseOrderDetailVoid($d) && (int)($d['status'] ?? 0) === 1) {
+            if (!$this->isPurchaseOrderDetailVoid($d) && ProcuremenStatus::isPodPicked($d['status'] ?? '')) {
                 $cn = trim((string)($d['company_name'] ?? ''));
                 $cn = trim((string)($d['company_name'] ?? ''));
                 if ($cn !== '') {
                 if ($cn !== '') {
                     return $cn;
                     return $cn;
@@ -4474,7 +4486,8 @@ class Procuremen extends Backend
                     'unit_price_text' => $amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : trim((string)($d['amount'] ?? '')),
                     'unit_price_text' => $amountNum !== null ? $this->formatProcuremenMoneyDisplay($amountNum) : trim((string)($d['amount'] ?? '')),
                     'subtotal_text'   => $sub !== null ? $this->formatProcuremenMoneyDisplay($sub) : '',
                     'subtotal_text'   => $sub !== null ? $this->formatProcuremenMoneyDisplay($sub) : '',
                     'delivery_ymd'    => $d['delivery_ymd'] ?? $this->formatDeliveryYmd($d['delivery'] ?? null),
                     'delivery_ymd'    => $d['delivery_ymd'] ?? $this->formatDeliveryYmd($d['delivery'] ?? null),
-                    'status'          => (int)($d['status'] ?? 0),
+                    'status'          => ProcuremenStatus::normalizePodPickStatus($d['status'] ?? ''),
+                    'is_picked'       => ProcuremenStatus::isPodPicked($d['status'] ?? ''),
                     'is_void'         => $isVoid,
                     'is_void'         => $isVoid,
                     'oper_time_text'  => $ct,
                     'oper_time_text'  => $ct,
                 ];
                 ];
@@ -4881,7 +4894,7 @@ class Procuremen extends Backend
             'cywyxm'        => $row['cywyxm'] ?? null,
             'cywyxm'        => $row['cywyxm'] ?? null,
             'This_quantity' => $row['This_quantity'] ?? $row['this_quantity'] ?? null,
             'This_quantity' => $row['This_quantity'] ?? $row['this_quantity'] ?? null,
             'ceilingPrice'  => $row['ceilingPrice'] ?? $row['ceiling_price'] ?? null,
             'ceilingPrice'  => $row['ceilingPrice'] ?? $row['ceiling_price'] ?? null,
-            'status'        => 0,
+            'status'        => ProcuremenStatus::PO_IN_PROGRESS,
             'sys_rq'        => $sysRqDb,
             'sys_rq'        => $sysRqDb,
         ];
         ];
         if ($wflowStatus !== null) {
         if ($wflowStatus !== null) {
@@ -4965,7 +4978,7 @@ class Procuremen extends Backend
                     'email'        => isset($c['email']) ? (string)$c['email'] : null,
                     'email'        => isset($c['email']) ? (string)$c['email'] : null,
                     'phone'        => isset($c['phone']) ? (string)$c['phone'] : null,
                     'phone'        => isset($c['phone']) ? (string)$c['phone'] : null,
                     'createtime'   => date('Y-m-d H:i:s'),
                     'createtime'   => date('Y-m-d H:i:s'),
-                    'status'       => 0,
+                    'status'       => ProcuremenStatus::POD_UNPICKED,
                     'status_name'  => '未提交',
                     'status_name'  => '未提交',
                 ];
                 ];
                 Db::table('purchase_order_detail')->insert($one);
                 Db::table('purchase_order_detail')->insert($one);
@@ -5599,16 +5612,13 @@ class Procuremen extends Backend
      */
      */
     protected function formatProcuremenRfqProgressText(array $row): string
     protected function formatProcuremenRfqProgressText(array $row): string
     {
     {
-        $st = trim((string)($row['status'] ?? ''));
-        // status=1 才表示主单已完结;status=0 为流程进行中(与详情 buildProcuremenDetailsViewData 一致)
-        if ($st === '1') {
-            return '已完结';
+        if (ProcuremenStatus::isPoCompleted($row['status'] ?? '')) {
+            return ProcuremenStatus::PO_COMPLETED;
         }
         }
-        $wf = (int)($row['wflow_status'] ?? 0);
-        if ($wf === 2) {
+        if (ProcuremenStatus::isWflowPendingApproval($row['wflow_status'] ?? '')) {
             return '待采购确认';
             return '待采购确认';
         }
         }
-        if ($wf === 1) {
+        if (ProcuremenStatus::isWflowPendingConfirm($row['wflow_status'] ?? '')) {
             return '待确认供应商';
             return '待确认供应商';
         }
         }
         $sid = (int)($row['scydgy_id'] ?? 0);
         $sid = (int)($row['scydgy_id'] ?? 0);
@@ -6024,8 +6034,8 @@ class Procuremen extends Backend
                     continue;
                     continue;
                 }
                 }
                 Db::table('purchase_order')->where('scydgy_id', $sid)->update([
                 Db::table('purchase_order')->where('scydgy_id', $sid)->update([
-                    'wflow_status'      => 2,
-                    'status'            => 0,
+                    'wflow_status'      => ProcuremenStatus::WFLOW_PENDING_APPROVAL,
+                    'status'            => ProcuremenStatus::PO_IN_PROGRESS,
                     'pick_company_name' => $companyName,
                     'pick_company_name' => $companyName,
                     'sys_rq'            => $sysRqDb,
                     'sys_rq'            => $sysRqDb,
                 ]);
                 ]);
@@ -6140,8 +6150,8 @@ class Procuremen extends Backend
         Db::table('purchase_order')
         Db::table('purchase_order')
             ->where('scydgy_id', 'in', array_keys($sids))
             ->where('scydgy_id', 'in', array_keys($sids))
             ->update([
             ->update([
-                'wflow_status'      => 0,
-                'status'            => 0,
+                'wflow_status'      => ProcuremenStatus::WFLOW_PENDING_ISSUE,
+                'status'            => ProcuremenStatus::PO_IN_PROGRESS,
                 'pick_company_name' => '',
                 'pick_company_name' => '',
                 'pick_time'         => null,
                 'pick_time'         => null,
                 'sys_rq'            => null,
                 'sys_rq'            => null,
@@ -6193,7 +6203,7 @@ class Procuremen extends Backend
         }
         }
         try {
         try {
             $query = Db::table('purchase_order')->where('CCYDH', $ccydh);
             $query = Db::table('purchase_order')->where('CCYDH', $ccydh);
-            $query->whereRaw("(TRIM(CAST(`status` AS CHAR)) = '1' OR CAST(`status` AS UNSIGNED) = 1)");
+            $query->whereRaw(ProcuremenStatus::sqlPoCompleted('status'));
             $pos = $query->order('scydgy_id', 'asc')->select();
             $pos = $query->order('scydgy_id', 'asc')->select();
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
             $pos = [$anchor];
             $pos = [$anchor];
@@ -6419,11 +6429,11 @@ class Procuremen extends Backend
         }
         }
 
 
         Db::table('purchase_order')->where('scydgy_id', $sid)->update([
         Db::table('purchase_order')->where('scydgy_id', $sid)->update([
-            'wflow_status'      => 1,
-            'status'            => 0,
+            'wflow_status'      => ProcuremenStatus::WFLOW_PENDING_CONFIRM,
+            'status'            => ProcuremenStatus::PO_IN_PROGRESS,
             'pick_company_name' => '',
             'pick_company_name' => '',
         ]);
         ]);
-        Db::table('purchase_order_detail')->where('scydgy_id', $sid)->update(['status' => 0]);
+        Db::table('purchase_order_detail')->where('scydgy_id', $sid)->update(['status' => ProcuremenStatus::POD_UNPICKED]);
         $this->restorePurchaseOrderDetailStatusNamesAfterReject($sid);
         $this->restorePurchaseOrderDetailStatusNamesAfterReject($sid);
 
 
         $poId = 0;
         $poId = 0;
@@ -6600,10 +6610,8 @@ class Procuremen extends Backend
             $po = null;
             $po = null;
         }
         }
         if (!$isPurchaseConfirm && is_array($po)) {
         if (!$isPurchaseConfirm && is_array($po)) {
-            $wf = (int)($po['wflow_status'] ?? 0);
-            $st = trim((string)($po['status'] ?? ''));
-            $isDone = ($st === '1' || $st === 1);
-            if ($wf === 2 && !$isDone) {
+            $isDone = ProcuremenStatus::isPoCompleted($po['status'] ?? '');
+            if (ProcuremenStatus::isWflowPendingApproval($po['wflow_status'] ?? '') && !$isDone) {
                 $isPurchaseConfirm = true;
                 $isPurchaseConfirm = true;
             }
             }
         }
         }
@@ -6759,9 +6767,19 @@ class Procuremen extends Backend
      *
      *
      * @param array<string, mixed> $row purchase_order 行
      * @param array<string, mixed> $row purchase_order 行
      */
      */
-    protected function resolveCompletedPurchaseOrderYm(array $row): string
+    protected function resolveCompletedPurchaseOrderYm(array $row, array $completeTsMap = []): string
     {
     {
-        foreach (['createtime', 'dStamp', 'updatetime'] as $key) {
+        $sid = (int)($row['scydgy_id'] ?? 0);
+        if ($sid > 0 && isset($completeTsMap[$sid]) && (int)$completeTsMap[$sid] > 946684800) {
+            return date('Y-m', (int)$completeTsMap[$sid]);
+        }
+        if ($sid > 0) {
+            $logTs = $this->resolveProcuremenOperLogTime($sid, ['purchase_confirm', 'mark_complete']);
+            if ($logTs !== '' && preg_match('/^(\d{4}-\d{2})/', $logTs, $m)) {
+                return $m[1];
+            }
+        }
+        foreach (['updatetime', 'createtime', 'dStamp'] as $key) {
             $raw = $row[$key] ?? null;
             $raw = $row[$key] ?? null;
             if ($raw === null || $raw === '') {
             if ($raw === null || $raw === '') {
                 continue;
                 continue;
@@ -6778,6 +6796,45 @@ class Procuremen extends Backend
         return '';
         return '';
     }
     }
 
 
+    /**
+     * @param array<int, string> $actions
+     * @return array<int, int>
+     */
+    protected function loadProcuremenOperLogTimestampMap(array $scydgyIds, array $actions): array
+    {
+        $out = [];
+        $scydgyIds = array_values(array_unique(array_filter(array_map('intval', $scydgyIds))));
+        $actions = array_values(array_filter(array_map('strval', $actions)));
+        if ($scydgyIds === [] || $actions === []) {
+            return $out;
+        }
+        try {
+            $logs = Db::table('purchase_order_oper_log')
+                ->where('scydgy_id', 'in', $scydgyIds)
+                ->where('action', 'in', $actions)
+                ->field('scydgy_id,createtime')
+                ->order('id', 'asc')
+                ->select();
+        } catch (\Throwable $e) {
+            $logs = [];
+        }
+        if (!is_array($logs)) {
+            return $out;
+        }
+        foreach ($logs as $log) {
+            if (!is_array($log)) {
+                continue;
+            }
+            $sid = (int)($log['scydgy_id'] ?? 0);
+            $ct = (int)($log['createtime'] ?? 0);
+            if ($sid > 0 && $ct > 946684800) {
+                $out[$sid] = isset($out[$sid]) ? max($out[$sid], $ct) : $ct;
+            }
+        }
+
+        return $out;
+    }
+
     /**
     /**
      * 按月份导出:已完结订单(与历史存证、月度列表一致),按完结月份筛选。
      * 按月份导出:已完结订单(与历史存证、月度列表一致),按完结月份筛选。
      * 表头固定 8 列(与历史「协助明细」模板一致):序号、传票号、传票名称、外加工单位、订法、客户名称、工序、加工金额。
      * 表头固定 8 列(与历史「协助明细」模板一致):序号、传票号、传票名称、外加工单位、订法、客户名称、工序、加工金额。
@@ -6793,7 +6850,7 @@ class Procuremen extends Backend
         $dbRows = [];
         $dbRows = [];
         try {
         try {
             $query = Db::table('purchase_order');
             $query = Db::table('purchase_order');
-            $query->whereRaw("(TRIM(CAST(`status` AS CHAR)) = '1' OR CAST(`status` AS UNSIGNED) = 1)");
+            $query->whereRaw(ProcuremenStatus::sqlPoCompleted('status'));
             $dbRows = $query->select();
             $dbRows = $query->select();
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
             $dbRows = [];
             $dbRows = [];
@@ -6801,12 +6858,26 @@ class Procuremen extends Backend
         if (!is_array($dbRows)) {
         if (!is_array($dbRows)) {
             $dbRows = [];
             $dbRows = [];
         }
         }
-        $dbRows = array_values(array_filter($dbRows, function ($dbRow) use ($ym) {
+        $completeTsMap = [];
+        $sidList = [];
+        foreach ($dbRows as $dbRow) {
+            if (!is_array($dbRow)) {
+                continue;
+            }
+            $sid = (int)($dbRow['scydgy_id'] ?? 0);
+            if ($sid > 0) {
+                $sidList[$sid] = true;
+            }
+        }
+        if ($sidList !== []) {
+            $completeTsMap = $this->loadProcuremenOperLogTimestampMap(array_keys($sidList), ['purchase_confirm', 'mark_complete']);
+        }
+        $dbRows = array_values(array_filter($dbRows, function ($dbRow) use ($ym, $completeTsMap) {
             if (!is_array($dbRow)) {
             if (!is_array($dbRow)) {
                 return false;
                 return false;
             }
             }
 
 
-            return $this->resolveCompletedPurchaseOrderYm($dbRow) === $ym;
+            return $this->resolveCompletedPurchaseOrderYm($dbRow, $completeTsMap) === $ym;
         }));
         }));
 
 
         $pool = $this->procuremenPoolFromPurchaseOrderDbRows($dbRows);
         $pool = $this->procuremenPoolFromPurchaseOrderDbRows($dbRows);
@@ -6828,7 +6899,7 @@ class Procuremen extends Backend
             try {
             try {
                 $detailRows = Db::table('purchase_order_detail')
                 $detailRows = Db::table('purchase_order_detail')
                     ->where('scydgy_id', 'in', array_keys($mainBySid))
                     ->where('scydgy_id', 'in', array_keys($mainBySid))
-                    ->where('status', '<>', self::PURCHASE_DETAIL_STATUS_VOID)
+                    ->whereRaw(ProcuremenStatus::sqlPodNotVoid('status'))
                     ->order('status', 'desc')
                     ->order('status', 'desc')
                     ->order('CCYDH', 'asc')
                     ->order('CCYDH', 'asc')
                     ->order('company_name', 'asc')
                     ->order('company_name', 'asc')
@@ -6838,7 +6909,7 @@ class Procuremen extends Backend
                 try {
                 try {
                     $detailRows = Db::table('purchase_order_detail')
                     $detailRows = Db::table('purchase_order_detail')
                         ->where('scydgy_id', 'in', array_keys($mainBySid))
                         ->where('scydgy_id', 'in', array_keys($mainBySid))
-                        ->where('status', '<>', self::PURCHASE_DETAIL_STATUS_VOID)
+                        ->whereRaw(ProcuremenStatus::sqlPodNotVoid('status'))
                         ->order('status', 'desc')
                         ->order('status', 'desc')
                         ->order('CCYDH', 'asc')
                         ->order('CCYDH', 'asc')
                         ->order('company_name', 'asc')
                         ->order('company_name', 'asc')
@@ -6866,7 +6937,7 @@ class Procuremen extends Backend
             if (isset($detailSidSeen[$sid])) {
             if (isset($detailSidSeen[$sid])) {
                 continue;
                 continue;
             }
             }
-            if ((int)($dr['status'] ?? 0) !== 1) {
+            if (!ProcuremenStatus::isPodPicked($dr['status'] ?? '')) {
                 continue;
                 continue;
             }
             }
             $detailSidSeen[$sid] = true;
             $detailSidSeen[$sid] = true;

+ 2 - 3
application/admin/controller/Procuremenarchive.php

@@ -3,6 +3,7 @@
 namespace app\admin\controller;
 namespace app\admin\controller;
 
 
 use app\common\controller\Backend;
 use app\common\controller\Backend;
+use app\common\library\ProcuremenStatus;
 use think\Db;
 use think\Db;
 
 
 /**
 /**
@@ -17,9 +18,7 @@ class Procuremenarchive extends Backend
     /** purchase_order.status 为已完结(兼容 varchar / 数字 / 首尾空格) */
     /** purchase_order.status 为已完结(兼容 varchar / 数字 / 首尾空格) */
     protected function applyPurchaseOrderCompletedWhere($query): void
     protected function applyPurchaseOrderCompletedWhere($query): void
     {
     {
-        $query->whereRaw(
-            "(TRIM(CAST(`status` AS CHAR)) = '1' OR CAST(`status` AS UNSIGNED) = 1)"
-        );
+        $query->whereRaw(ProcuremenStatus::sqlPoCompleted('status'));
     }
     }
 
 
     public function index()
     public function index()

+ 77 - 23
application/admin/controller/Procuremenexport.php

@@ -3,6 +3,7 @@
 namespace app\admin\controller;
 namespace app\admin\controller;
 
 
 use app\common\controller\Backend;
 use app\common\controller\Backend;
+use app\common\library\ProcuremenStatus;
 use think\Db;
 use think\Db;
 
 
 /**
 /**
@@ -65,7 +66,7 @@ class Procuremenexport extends Backend
     {
     {
         try {
         try {
             $query = Db::table('purchase_order');
             $query = Db::table('purchase_order');
-            $query->whereRaw("(TRIM(CAST(`status` AS CHAR)) = '1' OR CAST(`status` AS UNSIGNED) = 1)");
+            $query->whereRaw(ProcuremenStatus::sqlPoCompleted('status'));
             $dbRows = $query
             $dbRows = $query
                 ->field('id,scydgy_id,CCYDH,CYJMC,CGYMC,pick_time,createtime,dStamp,updatetime')
                 ->field('id,scydgy_id,CCYDH,CYJMC,CGYMC,pick_time,createtime,dStamp,updatetime')
                 ->order('id', 'desc')
                 ->order('id', 'desc')
@@ -88,18 +89,19 @@ class Procuremenexport extends Backend
             }
             }
         }
         }
         $amountMap = $this->loadDetailAmountSumByScydgyIds(array_keys($sidList));
         $amountMap = $this->loadDetailAmountSumByScydgyIds(array_keys($sidList));
+        $completeTsMap = $this->loadOperLogTimestampMap(array_keys($sidList), ['purchase_confirm', 'mark_complete']);
 
 
         $pool = [];
         $pool = [];
         foreach ($dbRows as $r) {
         foreach ($dbRows as $r) {
             if (!is_array($r)) {
             if (!is_array($r)) {
                 continue;
                 continue;
             }
             }
-            $rowYm = $this->resolvePurchaseOrderRowYm($r);
+            $rowYm = $this->resolvePurchaseOrderRowYm($r, $completeTsMap);
             if ($rowYm !== $ym) {
             if ($rowYm !== $ym) {
                 continue;
                 continue;
             }
             }
             $sid = (int)($r['scydgy_id'] ?? 0);
             $sid = (int)($r['scydgy_id'] ?? 0);
-            $doneText = $this->formatPurchaseOrderDoneTime($r);
+            $doneText = $this->formatPurchaseOrderDoneTime($r, $completeTsMap);
             $pool[] = [
             $pool[] = [
                 'id'              => (int)($r['id'] ?? 0),
                 'id'              => (int)($r['id'] ?? 0),
                 'scydgy_id'       => $sid,
                 'scydgy_id'       => $sid,
@@ -166,7 +168,7 @@ class Procuremenexport extends Backend
         try {
         try {
             $rows = Db::table('purchase_order_detail')
             $rows = Db::table('purchase_order_detail')
                 ->where('scydgy_id', 'in', $missing)
                 ->where('scydgy_id', 'in', $missing)
-                ->where('status', '<>', 2)
+                ->whereRaw(ProcuremenStatus::sqlPodNotVoid('status'))
                 ->field('scydgy_id,amount')
                 ->field('scydgy_id,amount')
                 ->select();
                 ->select();
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
@@ -207,7 +209,7 @@ class Procuremenexport extends Backend
         try {
         try {
             $rows = Db::table('purchase_order_detail')
             $rows = Db::table('purchase_order_detail')
                 ->where('scydgy_id', 'in', $scydgyIds)
                 ->where('scydgy_id', 'in', $scydgyIds)
-                ->where('status', 1)
+                ->whereIn('status', ProcuremenStatus::podPickedValues())
                 ->field('scydgy_id,amount')
                 ->field('scydgy_id,amount')
                 ->select();
                 ->select();
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
@@ -235,24 +237,16 @@ class Procuremenexport extends Backend
     }
     }
 
 
     /**
     /**
-     * 归属月份:与历史存证「完结时间」一致(createtime / dStamp),不用下发时间 pick_time
+     * 归属月份:优先采购确认/完结操作时间,其次 updatetime,再 createtime
      *
      *
      * @param array<string, mixed> $row
      * @param array<string, mixed> $row
+     * @param array<int, int>      $completeTsMap scydgy_id => unix 完结时间
      */
      */
-    protected function resolvePurchaseOrderRowYm(array $row): string
+    protected function resolvePurchaseOrderRowYm(array $row, array $completeTsMap = []): string
     {
     {
-        foreach (['createtime', 'dStamp', 'updatetime'] as $key) {
-            $raw = $row[$key] ?? null;
-            if ($raw === null || $raw === '') {
-                continue;
-            }
-            if (is_numeric($raw) && (int)$raw > 946684800) {
-                return date('Y-m', (int)$raw);
-            }
-            $t = trim((string)$raw);
-            if ($t !== '' && preg_match('/^(\d{4}-\d{2})/', $t, $m)) {
-                return $m[1];
-            }
+        $ts = $this->resolvePurchaseOrderCompleteTimestamp($row, $completeTsMap);
+        if ($ts > 0) {
+            return date('Y-m', $ts);
         }
         }
 
 
         return '';
         return '';
@@ -260,21 +254,81 @@ class Procuremenexport extends Backend
 
 
     /**
     /**
      * @param array<string, mixed> $row
      * @param array<string, mixed> $row
+     * @param array<int, int>    $completeTsMap
      */
      */
-    protected function formatPurchaseOrderDoneTime(array $row): string
+    protected function resolvePurchaseOrderCompleteTimestamp(array $row, array $completeTsMap = []): int
     {
     {
-        foreach (['createtime', 'dStamp', 'updatetime'] as $key) {
+        $sid = (int)($row['scydgy_id'] ?? 0);
+        if ($sid > 0 && isset($completeTsMap[$sid]) && (int)$completeTsMap[$sid] > 946684800) {
+            return (int)$completeTsMap[$sid];
+        }
+        foreach (['updatetime', 'createtime', 'dStamp'] as $key) {
             $raw = $row[$key] ?? null;
             $raw = $row[$key] ?? null;
             if ($raw === null || $raw === '') {
             if ($raw === null || $raw === '') {
                 continue;
                 continue;
             }
             }
             if (is_numeric($raw) && (int)$raw > 946684800) {
             if (is_numeric($raw) && (int)$raw > 946684800) {
-                return date('Y-m-d H:i:s', (int)$raw);
+                return (int)$raw;
             }
             }
             $t = trim((string)$raw);
             $t = trim((string)$raw);
             if ($t !== '' && stripos($t, '0000-00-00') !== 0) {
             if ($t !== '' && stripos($t, '0000-00-00') !== 0) {
-                return $t;
+                $parsed = (int)strtotime($t);
+
+                return $parsed > 946684800 ? $parsed : 0;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * @param array<int, string> $actions
+     * @return array<int, int> scydgy_id => 最近操作 unix 时间
+     */
+    protected function loadOperLogTimestampMap(array $scydgyIds, array $actions): array
+    {
+        $out = [];
+        $scydgyIds = array_values(array_unique(array_filter(array_map('intval', $scydgyIds))));
+        $actions = array_values(array_filter(array_map('strval', $actions)));
+        if ($scydgyIds === [] || $actions === []) {
+            return $out;
+        }
+        try {
+            $logs = Db::table('purchase_order_oper_log')
+                ->where('scydgy_id', 'in', $scydgyIds)
+                ->where('action', 'in', $actions)
+                ->field('scydgy_id,createtime')
+                ->order('id', 'asc')
+                ->select();
+        } catch (\Throwable $e) {
+            $logs = [];
+        }
+        if (!is_array($logs)) {
+            return $out;
+        }
+        foreach ($logs as $log) {
+            if (!is_array($log)) {
+                continue;
             }
             }
+            $sid = (int)($log['scydgy_id'] ?? 0);
+            $ct = (int)($log['createtime'] ?? 0);
+            if ($sid > 0 && $ct > 946684800) {
+                $out[$sid] = isset($out[$sid]) ? max($out[$sid], $ct) : $ct;
+            }
+        }
+
+        return $out;
+    }
+
+    /**
+     * @param array<string, mixed> $row
+     * @param array<int, int>    $completeTsMap
+     */
+    protected function formatPurchaseOrderDoneTime(array $row, array $completeTsMap = []): string
+    {
+        $ts = $this->resolvePurchaseOrderCompleteTimestamp($row, $completeTsMap);
+        if ($ts > 0) {
+            return date('Y-m-d H:i:s', $ts);
         }
         }
 
 
         return '';
         return '';

+ 2 - 2
application/admin/view/procuremen/audit_issue.html

@@ -183,8 +183,8 @@
             <thead>
             <thead>
             <tr>
             <tr>
                 <th class="text-center" style="width:42px;">选定</th>
                 <th class="text-center" style="width:42px;">选定</th>
-                <th style="min-width:140px;">公司名称</th>
-                <th style="width:88px;">联系人</th>
+                <th style="min-width:140px;">供应商名称</th>
+                <th style="width:88px;">姓名</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="width:120px;">手机号</th>
                 <th style="width:120px;">手机号</th>
                 <th style="min-width:120px;">工序名称</th>
                 <th style="min-width:120px;">工序名称</th>

+ 4 - 4
application/admin/view/procuremen/details_fragment.html

@@ -359,8 +359,8 @@
         <table class="table table-bordered table-condensed detail-mini detail-supplier-table">
         <table class="table table-bordered table-condensed detail-mini detail-supplier-table">
             <thead>
             <thead>
             <tr>
             <tr>
-                <th style="min-width:140px;">公司名称</th>
-                <th style="width:88px;">联系人</th>
+                <th style="min-width:140px;">供应商名称</th>
+                <th style="width:88px;">姓名</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="width:120px;">手机号</th>
                 <th style="width:120px;">手机号</th>
                 <th style="min-width:120px;">工序名称</th>
                 <th style="min-width:120px;">工序名称</th>
@@ -391,7 +391,7 @@
                 <td class="text-center">
                 <td class="text-center">
                     {if !empty($ln.is_void)}
                     {if !empty($ln.is_void)}
                     <span class="label label-default">历史</span>
                     <span class="label label-default">历史</span>
-                    {elseif $ln.status == 1 /}
+                    {elseif !empty($ln.is_picked) /}
                     <span class="label label-success">已选</span>
                     <span class="label label-success">已选</span>
                     {else /}
                     {else /}
                     <span class="text-muted"> </span>
                     <span class="text-muted"> </span>
@@ -423,7 +423,7 @@
                 <td class="text-center">
                 <td class="text-center">
                     {if isset($dr.is_void) && $dr.is_void}
                     {if isset($dr.is_void) && $dr.is_void}
                     <span class="label label-default">历史下发</span>
                     <span class="label label-default">历史下发</span>
-                    {elseif $dr.status == 1 /}
+                    {elseif !empty($dr.is_picked) /}
                     <span class="label label-success">已选</span>
                     <span class="label label-success">已选</span>
                     {else /}
                     {else /}
                     <span class="text-muted"> </span>
                     <span class="text-muted"> </span>

+ 3 - 3
application/admin/view/procuremen/outward_detail.html

@@ -187,8 +187,8 @@
             <thead>
             <thead>
             <tr>
             <tr>
                 <th class="text-center" style="width:42px;">选择</th>
                 <th class="text-center" style="width:42px;">选择</th>
-                <th style="min-width:140px;">公司名称</th>
-                <th style="width:88px;">联系人</th>
+                <th style="min-width:140px;">供应商名称</th>
+                <th style="width:88px;">姓名</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="width:120px;">手机号</th>
                 <th style="width:120px;">手机号</th>
                 <th style="min-width:120px;">工序名称</th>
                 <th style="min-width:120px;">工序名称</th>
@@ -267,7 +267,7 @@
                 <th class="col-title">印件名称</th>
                 <th class="col-title">印件名称</th>
                 <th class="col-amount">加工金额</th>
                 <th class="col-amount">加工金额</th>
                 <th class="col-delivery">交货日期</th>
                 <th class="col-delivery">交货日期</th>
-                <th>公司名称</th>
+                <th>供应商名称</th>
                 <th>邮箱</th>
                 <th>邮箱</th>
                 <th>手机号</th>
                 <th>手机号</th>
                 <th class="col-time">审核时间</th>
                 <th class="col-time">审核时间</th>

+ 1 - 1
application/admin/view/procuremen/review.html

@@ -543,7 +543,7 @@
                 </aside>
                 </aside>
                 <div class="review-company-main">
                 <div class="review-company-main">
                     <div class="review-company-toolbar">
                     <div class="review-company-toolbar">
-                        <input type="text" class="form-control" id="review-company-search" placeholder="搜索公司名称、联系人、邮箱、手机号、业务分类…" autocomplete="off"/>
+                        <input type="text" class="form-control" id="review-company-search" placeholder="搜索供应商名称、姓名、邮箱、手机号、业务分类…" autocomplete="off"/>
                     </div>
                     </div>
                     <div class="review-table-scroll">
                     <div class="review-table-scroll">
                         <div class="table-responsive">
                         <div class="table-responsive">

+ 1 - 1
application/admin/view/procuremenexport/index.html

@@ -12,7 +12,7 @@
                 </span>
                 </span>
             </div>
             </div>
             <table id="table" class="table table-striped table-bordered table-hover table-nowrap" width="100%"></table>
             <table id="table" class="table table-striped table-bordered table-hover table-nowrap" width="100%"></table>
-            <p class="help-block" style="padding:8px 12px;margin:0;">显示所选月份内<strong>已完结</strong>的协助订单(月份按历史存证中的「完结时间」统计,同一订单号合并为一行),点击「导出 Excel」下载该月协助明细。</p>
+            <p class="help-block" style="padding:8px 12px;margin:0;">显示所选月份内<strong>已完结</strong>的协助订单(月份按<strong>采购确认通过</strong>时间统计,同一订单号合并为一行),点击「导出 Excel」下载该月协助明细。</p>
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>

+ 199 - 0
application/common/library/ProcuremenStatus.php

@@ -0,0 +1,199 @@
+<?php
+
+namespace app\common\library;
+
+/**
+ * 协助采购状态文案(purchase_order / purchase_order_detail)
+ *
+ * purchase_order.status(主单是否完结):
+ *   进行中 — 协助流程未完结(已下发、待确认、待审批等)
+ *   已完结 — 采购确认通过,或协助初选直接点「完结」
+ *
+ * purchase_order.wflow_status(主单流程阶段,与 status 分工不同):
+ *   待下发 — 尚未协助下发,或退回初选后
+ *   待确认 — 已通知供应商报价,待采购选定供应商(原 1)
+ *   待审批 — 已选定供应商,待采购终审(原 2)
+ *
+ * purchase_order_detail.status(下发明细采购选定):
+ *   未选中 — 默认 / 未中标
+ *   已选中 — 采购确认选中的供应商明细(原 1)
+ *   已废弃 — 退回初选归档,不参与当前流程(原 2)
+ *
+ * purchase_order_detail.status_name(供应商填单 / 手机端 Tab,保持原中文):
+ *   未提交 / 已提交 / 已完成 / 未通过 / 已废弃
+ */
+class ProcuremenStatus
+{
+    public const PO_IN_PROGRESS = '进行中';
+    public const PO_COMPLETED = '已完结';
+
+    public const WFLOW_PENDING_ISSUE = '待下发';
+    public const WFLOW_PENDING_CONFIRM = '待确认';
+    public const WFLOW_PENDING_APPROVAL = '待审批';
+
+    public const POD_UNPICKED = '未选中';
+    public const POD_PICKED = '已选中';
+    public const POD_VOID = '已废弃';
+
+    public static function normalizePoStatus($value): string
+    {
+        $s = trim((string)$value);
+        if ($s === '' || $s === '0' || strcasecmp($s, self::PO_IN_PROGRESS) === 0) {
+            return self::PO_IN_PROGRESS;
+        }
+        if ($s === '1' || strcasecmp($s, self::PO_COMPLETED) === 0) {
+            return self::PO_COMPLETED;
+        }
+
+        return $s;
+    }
+
+    public static function isPoCompleted($value): bool
+    {
+        return self::normalizePoStatus($value) === self::PO_COMPLETED;
+    }
+
+    public static function isPoInProgress($value): bool
+    {
+        return self::normalizePoStatus($value) === self::PO_IN_PROGRESS;
+    }
+
+    public static function normalizeWflowStatus($value): string
+    {
+        $s = trim((string)$value);
+        if ($s === '' || $s === '0' || strcasecmp($s, self::WFLOW_PENDING_ISSUE) === 0) {
+            return self::WFLOW_PENDING_ISSUE;
+        }
+        if ($s === '1' || strcasecmp($s, self::WFLOW_PENDING_CONFIRM) === 0) {
+            return self::WFLOW_PENDING_CONFIRM;
+        }
+        if ($s === '2' || strcasecmp($s, self::WFLOW_PENDING_APPROVAL) === 0) {
+            return self::WFLOW_PENDING_APPROVAL;
+        }
+
+        return $s;
+    }
+
+    public static function isWflowPendingIssue($value): bool
+    {
+        return self::normalizeWflowStatus($value) === self::WFLOW_PENDING_ISSUE;
+    }
+
+    public static function isWflowPendingConfirm($value): bool
+    {
+        return self::normalizeWflowStatus($value) === self::WFLOW_PENDING_CONFIRM;
+    }
+
+    public static function isWflowPendingApproval($value): bool
+    {
+        return self::normalizeWflowStatus($value) === self::WFLOW_PENDING_APPROVAL;
+    }
+
+    public static function wflowAtLeastConfirm($value): bool
+    {
+        $w = self::normalizeWflowStatus($value);
+
+        return $w === self::WFLOW_PENDING_CONFIRM || $w === self::WFLOW_PENDING_APPROVAL;
+    }
+
+    public static function normalizePodPickStatus($value): string
+    {
+        $s = trim((string)$value);
+        if ($s === '' || $s === '0' || strcasecmp($s, self::POD_UNPICKED) === 0) {
+            return self::POD_UNPICKED;
+        }
+        if ($s === '1' || strcasecmp($s, self::POD_PICKED) === 0) {
+            return self::POD_PICKED;
+        }
+        if ($s === '2' || strcasecmp($s, self::POD_VOID) === 0 || strcasecmp($s, '已废弃') === 0) {
+            return self::POD_VOID;
+        }
+
+        return $s;
+    }
+
+    public static function isPodPicked($value): bool
+    {
+        return self::normalizePodPickStatus($value) === self::POD_PICKED;
+    }
+
+    public static function isPodVoid($value): bool
+    {
+        return self::normalizePodPickStatus($value) === self::POD_VOID;
+    }
+
+    /** @return string[] */
+    public static function wflowPendingConfirmValues(): array
+    {
+        return [self::WFLOW_PENDING_CONFIRM, '1'];
+    }
+
+    /** @return string[] */
+    public static function wflowPendingApprovalValues(): array
+    {
+        return [self::WFLOW_PENDING_APPROVAL, '2'];
+    }
+
+    /** @return string[] */
+    public static function wflowPendingIssueValues(): array
+    {
+        return [self::WFLOW_PENDING_ISSUE, '0', ''];
+    }
+
+    /** @return string[] */
+    public static function podPickedValues(): array
+    {
+        return [self::POD_PICKED, '1'];
+    }
+
+    /** @return string[] */
+    public static function podUnpickedValues(): array
+    {
+        return [self::POD_UNPICKED, '0', ''];
+    }
+
+    /** @return string[] */
+    public static function poCompletedValues(): array
+    {
+        return [self::PO_COMPLETED, '1'];
+    }
+
+    /** @return string[] */
+    public static function poInProgressValues(): array
+    {
+        return [self::PO_IN_PROGRESS, '0'];
+    }
+
+    public static function sqlPoCompleted(string $column = 'status'): string
+    {
+        $c = self::quoteSqlIdent($column);
+
+        return "(TRIM(CAST({$c} AS CHAR)) IN ('" . self::PO_COMPLETED . "','1') OR CAST({$c} AS UNSIGNED) = 1)";
+    }
+
+    public static function sqlPoInProgress(string $column = 'status'): string
+    {
+        $c = self::quoteSqlIdent($column);
+
+        return "(TRIM(CAST({$c} AS CHAR)) IN ('" . self::PO_IN_PROGRESS . "','0') OR CAST({$c} AS UNSIGNED) = 0)";
+    }
+
+    public static function sqlPodNotVoid(string $column = 'status'): string
+    {
+        $c = self::quoteSqlIdent($column);
+        $void = self::POD_VOID;
+
+        return "({$c} IS NULL OR TRIM(CAST({$c} AS CHAR)) NOT IN ('{$void}','2') AND CAST({$c} AS UNSIGNED) <> 2)";
+    }
+
+    protected static function quoteSqlIdent(string $column): string
+    {
+        if (strpos($column, '.') !== false) {
+            $parts = explode('.', $column, 2);
+
+            return '`' . str_replace('`', '', $parts[0]) . '`.`' . str_replace('`', '', $parts[1]) . '`';
+        }
+
+        return '`' . str_replace('`', '', $column) . '`';
+    }
+}

+ 33 - 0
application/extra/procuremen_status_to_chinese.sql

@@ -0,0 +1,33 @@
+-- 协助采购:status / wflow_status 由数字改为中文(执行前请备份)
+-- 说明见 application/common/library/ProcuremenStatus.php
+
+-- ========== purchase_order ==========
+-- status:主单是否完结
+--   0 / 进行中 → 进行中
+--   1 / 已完结 → 已完结
+UPDATE `purchase_order` SET `status` = '进行中' WHERE `status` IS NULL OR TRIM(CAST(`status` AS CHAR)) IN ('0', '进行中');
+UPDATE `purchase_order` SET `status` = '已完结' WHERE TRIM(CAST(`status` AS CHAR)) IN ('1', '已完结');
+
+-- wflow_status:流程阶段(建议列改为 varchar,见下方 ALTER)
+--   0 / 待下发 → 待下发
+--   1 / 待确认 → 待确认(待确认供应商)
+--   2 / 待审批 → 待审批(待采购确认)
+UPDATE `purchase_order` SET `wflow_status` = '待下发' WHERE `wflow_status` IS NULL OR TRIM(CAST(`wflow_status` AS CHAR)) IN ('0', '待下发');
+UPDATE `purchase_order` SET `wflow_status` = '待确认' WHERE TRIM(CAST(`wflow_status` AS CHAR)) IN ('1', '待确认');
+UPDATE `purchase_order` SET `wflow_status` = '待审批' WHERE TRIM(CAST(`wflow_status` AS CHAR)) IN ('2', '待审批');
+
+-- 可选:将 wflow_status 改为 varchar(若当前为 tinyint)
+-- ALTER TABLE `purchase_order` MODIFY COLUMN `wflow_status` varchar(16) NOT NULL DEFAULT '待下发' COMMENT '待下发|待确认|待审批';
+-- ALTER TABLE `purchase_order` MODIFY COLUMN `status` varchar(16) DEFAULT NULL COMMENT '进行中|已完结';
+
+-- ========== purchase_order_detail ==========
+-- status:采购选定(与 status_name 不同;status_name 为供应商填单状态)
+--   0 / 未选中 → 未选中
+--   1 / 已选中 → 已选中
+--   2 / 已废弃 → 已废弃
+UPDATE `purchase_order_detail` SET `status` = '未选中' WHERE `status` IS NULL OR TRIM(CAST(`status` AS CHAR)) IN ('0', '未选中');
+UPDATE `purchase_order_detail` SET `status` = '已选中' WHERE TRIM(CAST(`status` AS CHAR)) IN ('1', '已选中');
+UPDATE `purchase_order_detail` SET `status` = '已废弃' WHERE TRIM(CAST(`status` AS CHAR)) IN ('2', '已废弃');
+
+-- 可选:
+-- ALTER TABLE `purchase_order_detail` MODIFY COLUMN `status` varchar(16) NOT NULL DEFAULT '未选中' COMMENT '未选中|已选中|已废弃';

+ 22 - 10
application/extra/procuremen_workflow.sql

@@ -1,16 +1,28 @@
 -- 协助三步流程(仅保留必要列;若列已存在会报错,可跳过)
 -- 协助三步流程(仅保留必要列;若列已存在会报错,可跳过)
--- ① 协助下发 pick:选工序+多家供应商,发短信邮件通知报价 → wflow_status=1
--- ② 确认供应商 audit:从已通知的报价中选一家 → wflow_status=2,不发短信
--- ③ 采购确认 confirm:定标,发送通过/未通过短信 → status 完结等
--- purchase_order.status(与 wflow_status 不同):
---   空/null = 未完结:仅保存本次数量/最高限价,或尚未写入状态
---   0       = 协助流程进行中(已下发/待确认供应商/待采购确认,未点「完结」)
---   1       = 已完结(协助下发点「完结」,或采购确认提交成功)
--- wflow_status:0待下发 1待确认供应商 2待采购确认(三步菜单用)
--- wflow_status:流程阶段,与 status 分工不同,不能只用 status 代替
+-- ① 协助下发 pick:选工序+多家供应商,发短信邮件通知报价 → wflow_status=待确认
+-- ② 确认供应商 audit:从已通知的报价中选一家 → wflow_status=待审批,不发短信
+-- ③ 采购确认 confirm:定标,发送通过/未通过短信 → status=已完结 等
+--
+-- purchase_order.status(主单是否完结,与 wflow_status 分工不同):
+--   空/null = 未写入(仅保存本次数量/最高限价,尚未进入协助流程)
+--   进行中   = 协助流程未完结(已下发、待确认、待审批等)
+--   已完结   = 协助下发点「完结」,或采购确认提交成功
+--
+-- purchase_order.wflow_status(主单流程阶段):
+--   待下发 = 尚未协助下发,或退回初选后
+--   待确认 = 已通知供应商报价,待采购选定供应商
+--   待审批 = 已选定供应商,待采购终审
+--
+-- purchase_order_detail.status(下发明细采购选定,与 status_name 不同):
+--   未选中 / 已选中 / 已废弃
+--
+-- purchase_order_detail.status_name(供应商填单 / 手机端 Tab):
+--   未提交 / 已提交 / 已完成 / 未通过 / 已废弃
+--
+-- 数字改中文迁移脚本见:procuremen_status_to_chinese.sql
 
 
 ALTER TABLE `purchase_order`
 ALTER TABLE `purchase_order`
-  ADD COLUMN `wflow_status` tinyint(3) unsigned NOT NULL DEFAULT 0 COMMENT '0待下发1待确认供应商2待采购确认' AFTER `status`,
+  ADD COLUMN `wflow_status` varchar(16) NOT NULL DEFAULT '待下发' COMMENT '待下发|待确认|待审批' AFTER `status`,
   ADD COLUMN `pick_company_name` varchar(200) DEFAULT '' COMMENT '第二步确认供应商选定' AFTER `wflow_status`,
   ADD COLUMN `pick_company_name` varchar(200) DEFAULT '' COMMENT '第二步确认供应商选定' AFTER `wflow_status`,
   ADD COLUMN `pick_time` datetime DEFAULT NULL COMMENT '下发时间' AFTER `pick_company_name`;
   ADD COLUMN `pick_time` datetime DEFAULT NULL COMMENT '下发时间' AFTER `pick_company_name`;
 
 

+ 6 - 5
application/index/controller/Index.php

@@ -3,6 +3,7 @@
 namespace app\index\controller;
 namespace app\index\controller;
 
 
 use app\common\controller\Frontend;
 use app\common\controller\Frontend;
+use app\common\library\ProcuremenStatus;
 use think\Cache;
 use think\Cache;
 use think\captcha\Captcha;
 use think\captcha\Captcha;
 use think\Config;
 use think\Config;
@@ -1604,16 +1605,16 @@ class Index extends Frontend
 
 
             return $this->mprocDetailQuoteSubmitted($row) ? '已提交' : '未提交';
             return $this->mprocDetailQuoteSubmitted($row) ? '已提交' : '未提交';
         }
         }
-        $poStatus = (int)($po['status'] ?? $po['STATUS'] ?? 0);
-        if ($poStatus !== 1) {
+        $poStatus = $po['status'] ?? $po['STATUS'] ?? '';
+        if (!ProcuremenStatus::isPoCompleted($poStatus)) {
             if ($sn !== '') {
             if ($sn !== '') {
                 return $sn;
                 return $sn;
             }
             }
 
 
             return $this->mprocDetailQuoteSubmitted($row) ? '已提交' : '未提交';
             return $this->mprocDetailQuoteSubmitted($row) ? '已提交' : '未提交';
         }
         }
-        $detailStatus = (int)($row['status'] ?? $row['STATUS'] ?? 0);
-        if ($detailStatus === 1) {
+        $detailStatus = $row['status'] ?? $row['STATUS'] ?? '';
+        if (ProcuremenStatus::isPodPicked($detailStatus)) {
             return '已完成';
             return '已完成';
         }
         }
         if ($sn === '已提交') {
         if ($sn === '已提交') {
@@ -1678,7 +1679,7 @@ class Index extends Frontend
         try {
         try {
             $poRows = Db::table('purchase_order')
             $poRows = Db::table('purchase_order')
                 ->where('scydgy_id', 'in', array_keys($sidList))
                 ->where('scydgy_id', 'in', array_keys($sidList))
-                ->where('status', 1)
+                ->whereIn('status', ProcuremenStatus::poCompletedValues())
                 ->select();
                 ->select();
             if (is_array($poRows)) {
             if (is_array($poRows)) {
                 foreach ($poRows as $pr) {
                 foreach ($poRows as $pr) {

+ 1 - 1
public/assets/js/backend/procuremenarchive.js

@@ -127,7 +127,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     return;
                     return;
                 }
                 }
                 var url = Fast.api.fixurl('procuremen/details?ids=' + encodeURIComponent(String(sid)));
                 var url = Fast.api.fixurl('procuremen/details?ids=' + encodeURIComponent(String(sid)));
-                Backend.api.open(url, '详情', {area: ['76%', '100%']});
+                Backend.api.open(url, '详情', {area: ['92%', '88%']});
             });
             });
 
 
             $(document).off('click.procuremenArchiveAbandon', '#btn-archive-abandon').on('click.procuremenArchiveAbandon', '#btn-archive-abandon', function (e) {
             $(document).off('click.procuremenArchiveAbandon', '#btn-archive-abandon').on('click.procuremenArchiveAbandon', '#btn-archive-abandon', function (e) {

+ 1 - 1
public/assets/js/backend/procuremenexport.js

@@ -99,7 +99,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     return;
                     return;
                 }
                 }
                 var url = Fast.api.fixurl('procuremen/details?ids=' + encodeURIComponent(String(sid)));
                 var url = Fast.api.fixurl('procuremen/details?ids=' + encodeURIComponent(String(sid)));
-                Backend.api.open(url, '详情', {area: ['76%', '100%']});
+                Backend.api.open(url, '详情', {area: ['92%', '88%']});
             });
             });
         },
         },
         api: {
         api: {