m0_70156489 1 неделя назад
Родитель
Сommit
05eddc7a56

+ 13 - 13
application/admin/view/index/login.html

@@ -6,8 +6,8 @@
         body {
             width: 100%;
             height: 100vh;
-            /* background-image: url("http://xh-erp.7in6.com/img/bg1.jpg"); */
-            background-color: #071d31;
+             background-image: url("http://xh-erp.7in6.com/img/bg1.jpg");
+            /*background-color: #071d31;*/
             background-size: cover;
             background-repeat: no-repeat;
             display: flex;
@@ -157,17 +157,17 @@
             }
         }
     </style>
-    <!--@formatter:off-->
-    {if $background}
-    <style type="text/css">
-        body {
-            background-image: url('{$background}');
-            background-image: url("./img/bg.jpg");
-            filter: brightness(1.2); /* 调整亮度 */
-        }
-    </style>
-    {/if}
-    <!--@formatter:on-->
+<!--    &lt;!&ndash;@formatter:off&ndash;&gt;-->
+<!--    {if $background}-->
+<!--    <style type="text/css">-->
+<!--        body {-->
+<!--            background-image: url('{$background}');-->
+<!--            background-image: url("./img/bg1.jpg");-->
+<!--            filter: brightness(1.2); /* 调整亮度 */-->
+<!--        }-->
+<!--    </style>-->
+<!--    {/if}-->
+<!--    &lt;!&ndash;@formatter:on&ndash;&gt;-->
     <script>
         // 禁止页面缩放
         document.addEventListener('wheel', function(e) {

+ 19 - 7
application/admin/view/procuremen/index.html

@@ -1,9 +1,9 @@
 <style>
-    /* 工具栏贴右时避免被 #content / .col / .content 裁切 */
+    /* 工具栏贴右时避免被裁切;主内容区约束宽度,表格在内部横向滚动 */
     #content:has(#procuremen-layout),
     #content .col-xs-12:has(#procuremen-layout),
     div.content:has(#procuremen-layout) {
-        overflow-x: visible !important;
+        overflow-x: hidden !important;
     }
     div.content:has(#procuremen-layout) {
         padding-top: 0 !important;
@@ -49,8 +49,9 @@
         }
     }
     #procuremen-layout .procuremen-main {
-        overflow-x: visible !important;
-        padding-right: 18px !important;
+        overflow-x: hidden !important;
+        overflow-y: visible;
+        padding-right: 12px !important;
         flex: 1 1 0%;
         min-width: 0;
     }
@@ -90,10 +91,11 @@
         border-color: #367fa9;
     }
     #procuremen-layout .procuremen-main .widget-body {
-        overflow-x: visible;
+        overflow-x: hidden;
         overflow-y: hidden;
         flex: 1 1 auto;
         min-height: 0;
+        min-width: 0;
         display: flex;
         flex-direction: column;
     }
@@ -189,6 +191,7 @@
     #procuremen-layout .procuremen-main .procuremen-table-area {
         flex: 1 1 auto;
         min-height: 0;
+        min-width: 0;
         overflow: hidden;
         display: flex;
         flex-direction: column;
@@ -196,6 +199,11 @@
     #procuremen-layout .procuremen-table-area > .bootstrap-table {
         flex: 1 1 auto;
         min-height: 0;
+        min-width: 0;
+        width: 100%;
+    }
+    #procuremen-layout .bootstrap-table .fixed-table-container {
+        width: 100% !important;
     }
     .procuremen-table-area .toolbar.procuremen-toolbar-empty {
         display: none !important;
@@ -248,9 +256,13 @@
         min-height: 28px;
         cursor: pointer;
     }
-    /* 避免出现纵向滚动条时表头与表体列宽错位 */
+    /* 表头与表体同步横向滚动,避免右侧列(如提交日期)被裁切 */
     #procuremen-layout .bootstrap-table .fixed-table-body {
-        overflow-y: auto;
+        overflow: auto !important;
+        -webkit-overflow-scrolling: touch;
+    }
+    #procuremen-layout .bootstrap-table .fixed-table-header {
+        overflow: hidden;
     }
     #procuremen-layout .nice-validator .bootstrap-table td.bs-checkbox input[type="checkbox"],
     #procuremen-layout .nice-validator .bootstrap-table th.bs-checkbox input[type="checkbox"] {

+ 139 - 38
application/common/library/ProcuremenDashboard.php

@@ -48,7 +48,6 @@ class ProcuremenDashboard
         $todayEnd = date('Y-m-d H:i:s');
         $monthStart = date('Y-m-01 00:00:00');
         $monthEnd = date('Y-m-t 23:59:59');
-        $pending = self::countCurrentPending();
 
         return [
             'supplier' => [
@@ -57,14 +56,14 @@ class ProcuremenDashboard
                 'link_text' => '',
             ],
             'confirm' => [
-                'today'     => (int)$pending['confirm'],
-                'month'     => self::countOperLogDistinctOrdersInRange(['issue_submit'], $monthStart, $monthEnd),
+                'today'     => self::countOperLogDistinctOrdersInRange(['issue_submit'], $todayStart, $todayEnd),
+                'month'     => self::countPendingStageOrdersInMonth('confirm', $monthStart, $monthEnd),
                 'link'      => 'procuremen/audit',
                 'link_text' => '供应商确认',
             ],
             'approval' => [
-                'today'     => (int)$pending['approval'],
-                'month'     => self::countOperLogDistinctOrdersInRange(['audit_select'], $monthStart, $monthEnd),
+                'today'     => self::countOperLogDistinctOrdersInRange(['audit_select'], $todayStart, $todayEnd),
+                'month'     => self::countPendingStageOrdersInMonth('approval', $monthStart, $monthEnd),
                 'link'      => 'procuremen/confirm',
                 'link_text' => '供应商审批',
             ],
@@ -410,33 +409,12 @@ class ProcuremenDashboard
             $startTs,
             $endTs
         );
-        $confirmBuckets = self::emptyDayBuckets($dayKeys);
-
-        try {
-            $expr = self::pickTimeSqlExpr();
-            $query = Db::table('purchase_order')->field('CCYDH,pick_time,createtime,dputrecord,dStamp,wflow_status,status');
-            self::applyNotDeletedWhere($query);
-            $query->whereRaw("({$expr}) >= ? AND ({$expr}) <= ?", [$rangeStart, $rangeEnd]);
-            $rows = $query->select();
-        } catch (\Throwable $e) {
-            $rows = [];
-        }
-        if (is_array($rows)) {
-            foreach ($rows as $row) {
-                if (!is_array($row)) {
-                    continue;
-                }
-                $day = self::resolveRowDayKey($row, $dayKeys);
-                if ($day === null) {
-                    continue;
-                }
-                $orderKey = self::resolveOrderKey($row);
-                if (self::isPendingConfirmRow($row)) {
-                    $confirmBuckets[$day][$orderKey] = true;
-                }
-            }
-        }
-
+        $confirmBuckets = self::bucketOperLogOrdersByDay(
+            self::loadOperLogsInRange(['issue_submit'], $startTs, $endTs),
+            $dayKeys,
+            $startTs,
+            $endTs
+        );
         $approvalBuckets = self::bucketOperLogOrdersByDay(
             self::loadOperLogsInRange(['audit_select'], $startTs, $endTs),
             $dayKeys,
@@ -643,19 +621,142 @@ class ProcuremenDashboard
         return count($keys);
     }
 
+    /**
+     * 本月待处理:与「确认供应商 / 采购确认」列表一致(当前队列 + 下发月份 + 订单号去重)
+     */
+    protected static function countPendingStageOrdersInMonth(string $stage, string $monthStart, string $monthEnd): int
+    {
+        $rows = self::loadPendingStageRowsWithTime($stage);
+        if ($rows === []) {
+            return 0;
+        }
+        $matched = [];
+        foreach ($rows as $row) {
+            if (!is_array($row)) {
+                continue;
+            }
+            $normalized = self::normalizeRowForListMonth($row);
+            if (!self::rowMatchesMonthRange($normalized, $monthStart, $monthEnd, 'pick_time')) {
+                continue;
+            }
+            $matched[] = $normalized;
+        }
+
+        return self::countDistinctOrders($matched);
+    }
+
+    /**
+     * @return array<int, array<string, mixed>>
+     */
+    protected static function loadPendingStageRowsWithTime(string $stage): array
+    {
+        try {
+            $fields = 'id,CCYDH,scydgy_id,pick_time,createtime,dputrecord,dStamp,wflow_status,status';
+            $query = Db::table('purchase_order')->field($fields);
+            self::applyNotDeletedWhere($query);
+            if ($stage === 'confirm') {
+                $query->whereIn('wflow_status', ProcuremenStatus::wflowPendingConfirmValues());
+            } else {
+                $vals = ProcuremenStatus::wflowPendingApprovalValues();
+                $quoted = [];
+                foreach ($vals as $v) {
+                    $quoted[] = "'" . str_replace("'", "''", (string)$v) . "'";
+                }
+                if ($quoted === []) {
+                    return [];
+                }
+                $query->whereRaw('TRIM(CAST(wflow_status AS CHAR)) IN (' . implode(',', $quoted) . ')');
+                $query->whereRaw('NOT (' . ProcuremenStatus::sqlPoCompleted('status') . ')');
+            }
+            $rows = $query->select();
+        } catch (\Throwable $e) {
+            return [];
+        }
+
+        return is_array($rows) ? $rows : [];
+    }
+
+    /**
+     * 列表月份筛选前补齐时间字段(与 buildListRowFromPurchaseOrderDbRow 回退一致)
+     *
+     * @param array<string, mixed> $row
+     * @return array<string, mixed>
+     */
+    protected static function normalizeRowForListMonth(array $row): array
+    {
+        $r = $row;
+        $r['createtime'] = ProcuremenTime::formatDisplayDateTime($row['createtime'] ?? null);
+
+        $dpOut = trim((string)($r['dputrecord'] ?? ''));
+        if ($dpOut === '' || stripos($dpOut, '0000-00-00') === 0) {
+            $fallback = trim((string)($r['dStamp'] ?? ''));
+            if ($fallback !== '' && stripos($fallback, '0000-00-00') !== 0) {
+                $r['dputrecord'] = $fallback;
+            } elseif ($r['createtime'] !== '') {
+                $r['dputrecord'] = $r['createtime'];
+            }
+        }
+
+        $pickOut = trim((string)($r['pick_time'] ?? ''));
+        if ($pickOut === '' || stripos($pickOut, '0000-00-00') === 0) {
+            foreach (['createtime', 'dputrecord', 'dStamp'] as $pickFallbackKey) {
+                $pickFallback = trim((string)($r[$pickFallbackKey] ?? ''));
+                if ($pickFallback !== '' && stripos($pickFallback, '0000-00-00') !== 0) {
+                    $r['pick_time'] = $pickFallback;
+                    break;
+                }
+            }
+        }
+
+        return $r;
+    }
+
+    /**
+     * @param array<string, mixed> $row
+     */
+    protected static function resolveRowListTime(array $row, string $primary = 'pick_time'): string
+    {
+        $keys = array_values(array_unique([$primary, 'pick_time', 'createtime', 'dputrecord', 'dStamp']));
+        foreach ($keys as $k) {
+            $t = trim((string)($row[$k] ?? ''));
+            if ($t !== '' && stripos($t, '0000-00-00') !== 0) {
+                return $t;
+            }
+        }
+
+        return '';
+    }
+
+    /**
+     * @param array<string, mixed> $row
+     */
+    protected static function rowMatchesMonthRange(array $row, string $monthStart, string $monthEnd, string $primary = 'pick_time'): bool
+    {
+        $listTime = self::resolveRowListTime($row, $primary);
+        if ($listTime === '' || stripos($listTime, '0000-00-00') === 0
+            || !preg_match('/^([12]\d{3})-(\d{1,2})-(\d{1,2})/', $listTime, $m)) {
+            return false;
+        }
+        $mo = (int)$m[2];
+        if ($mo < 1 || $mo > 12) {
+            return false;
+        }
+        $ymRow = $m[1] . '-' . str_pad((string)$mo, 2, '0', STR_PAD_LEFT);
+        $rowMonthStart = $ymRow . '-01 00:00:00';
+        $rowMonthEnd = date('Y-m-t 23:59:59', strtotime($rowMonthStart));
+
+        return !(strcmp($rowMonthEnd, $monthStart) < 0 || strcmp($rowMonthStart, $monthEnd) > 0);
+    }
+
     /**
      * @return array{issued:int,confirm:int,approval:int,completed:int}
      */
     protected static function countStageMetrics(string $start, string $end): array
     {
-        $pending = self::countCurrentPending();
-
         return [
-            // 已下发:本时段内通知下发,且当前已离开「待确认」队列(不与待确认重复)
             'issued'    => self::countIssuedInRange($start, $end),
-            // 待确认 / 待审批:与列表一致,统计当前积压(不按 pick_time 截断)
-            'confirm'   => $pending['confirm'],
-            'approval'  => $pending['approval'],
+            'confirm'   => self::countOperLogDistinctOrdersInRange(['issue_submit'], $start, $end),
+            'approval'  => self::countOperLogDistinctOrdersInRange(['audit_select'], $start, $end),
             'completed' => self::countCompletedInRange($start, $end),
         ];
     }