From 909164aa1859fdf25330eb130bc90b8bd22e540b Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 24 三月 2026 12:00:51 +0800
Subject: [PATCH] #

---
 src/main/webapp/views/wrkAnalysis/wrkAnalysis.html |  213 ++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 160 insertions(+), 53 deletions(-)

diff --git a/src/main/webapp/views/wrkAnalysis/wrkAnalysis.html b/src/main/webapp/views/wrkAnalysis/wrkAnalysis.html
index ee6ac39..d18b9fe 100644
--- a/src/main/webapp/views/wrkAnalysis/wrkAnalysis.html
+++ b/src/main/webapp/views/wrkAnalysis/wrkAnalysis.html
@@ -113,6 +113,11 @@
             font-weight: 700;
             color: #22364a;
         }
+        .summary-value.datetime {
+            font-size: 20px;
+            line-height: 1.25;
+            word-break: break-word;
+        }
         .summary-sub {
             margin-top: 8px;
             font-size: 12px;
@@ -166,6 +171,35 @@
             color: #b56c05;
             background: rgba(245, 163, 74, 0.16);
             border-color: rgba(245, 163, 74, 0.18);
+        }
+        .export-mode {
+            background: #ffffff;
+        }
+        .export-detail-table {
+            width: 100%;
+            border-collapse: collapse;
+            table-layout: fixed;
+            font-size: 12px;
+            color: #22364a;
+            background: #ffffff;
+        }
+        .export-detail-table th,
+        .export-detail-table td {
+            border: 1px solid #dfe7f0;
+            padding: 8px 6px;
+            text-align: center;
+            vertical-align: middle;
+            word-break: break-all;
+        }
+        .export-detail-table th {
+            background: #f5f8fc;
+            font-weight: 700;
+        }
+        .export-section-title {
+            margin: 0 0 10px;
+            font-size: 16px;
+            font-weight: 700;
+            color: #22364a;
         }
         @media (max-width: 1460px) {
             .filter-grid,
@@ -333,71 +367,142 @@
         </div>
     </section>
 
-    <section class="panel">
+    <section ref="analysisExportRoot" class="panel" :class="{ 'export-mode': exportingPdf }">
         <div class="panel-head">
             <div class="panel-title">鍒嗘瀽缁撴灉</div>
+            <el-button
+                    data-html2canvas-ignore="true"
+                    size="small"
+                    type="primary"
+                    plain
+                    :disabled="!analysisReady"
+                    :loading="exportingPdf"
+                    @click="exportAnalysisPdf">瀵煎嚭PDF</el-button>
         </div>
         <div class="panel-body">
-            <div v-if="analysis.summary.partialTaskCount > 0" class="quality-banner">
-                褰撳墠缁撴灉涓湁 {{ analysis.summary.partialTaskCount }} 鏉″巻鍙蹭换鍔$己灏戦樁娈甸噰闆嗭紝浠呭弬涓庢�昏�楁椂鍜屾晠闅滅粺璁°��
-            </div>
-
             <div v-if="!analysisReady" class="empty-shell">鍏堜粠涓婃柟绛涢�変换鍔℃垨鏃堕棿鑼冨洿锛岀劧鍚庢墽琛屽垎鏋愩��</div>
             <template v-else>
-                <div class="summary-grid">
-                    <div class="summary-card">
-                        <div class="summary-label">浠诲姟鏁�</div>
-                        <div class="summary-value">{{ formatNumber(analysis.summary.taskCount) }}</div>
-                        <div class="summary-sub">鏈鍒嗘瀽鍛戒腑浠诲姟鎬绘暟</div>
+                <div ref="analysisVisualRoot">
+                    <div v-if="analysis.summary.partialTaskCount > 0" class="quality-banner">
+                        褰撳墠缁撴灉涓湁 {{ analysis.summary.partialTaskCount }} 鏉″巻鍙蹭换鍔$己灏戦樁娈甸噰闆嗭紝浠呭弬涓庢�昏�楁椂鍜屾晠闅滅粺璁°��
                     </div>
-                    <div class="summary-card">
-                        <div class="summary-label">骞冲潎鎬昏�楁椂</div>
-                        <div class="summary-value">{{ formatDuration(analysis.summary.avgTotalDurationMs) }}</div>
-                        <div class="summary-sub">鍒涘缓鍒板畬鎴愮殑骞冲潎鑰楁椂</div>
-                    </div>
-                    <div class="summary-card">
-                        <div class="summary-label">骞冲潎绔欑偣鑰楁椂</div>
-                        <div class="summary-value">{{ formatDuration(analysis.summary.avgStationDurationMs) }}</div>
-                        <div class="summary-sub">浠呯粺璁″畬鏁撮樁娈垫暟鎹�</div>
-                    </div>
-                    <div class="summary-card">
-                        <div class="summary-label">骞冲潎鍫嗗灈鏈鸿�楁椂</div>
-                        <div class="summary-value">{{ formatDuration(analysis.summary.avgCraneDurationMs) }}</div>
-                        <div class="summary-sub">浠呯粺璁″畬鏁撮樁娈垫暟鎹�</div>
-                    </div>
-                    <div class="summary-card">
-                        <div class="summary-label">鏁呴殰浠诲姟鏁�</div>
-                        <div class="summary-value">{{ formatNumber(analysis.summary.faultTaskCount) }}</div>
-                        <div class="summary-sub">鍑虹幇璁惧鏁呴殰鐨勪换鍔℃暟</div>
-                    </div>
-                    <div class="summary-card">
-                        <div class="summary-label">鎬绘晠闅滆�楁椂</div>
-                        <div class="summary-value">{{ formatDuration(analysis.summary.faultDurationMs) }}</div>
-                        <div class="summary-sub">鍗曞爢鍨涙満 / 鍙屽伐浣� / RGV</div>
-                    </div>
-                </div>
 
-                <div class="chart-grid" style="margin-top: 16px;">
-                    <div class="chart-card">
-                        <div class="chart-title">浠诲姟鑰楁椂瀵规瘮</div>
-                        <div ref="durationChart" class="chart-box"></div>
+                    <div class="summary-grid">
+                        <div class="summary-card">
+                            <div class="summary-label">浠诲姟鏁�</div>
+                            <div class="summary-value">{{ formatNumber(analysis.summary.taskCount) }}</div>
+                            <div class="summary-sub">鏈鍒嗘瀽鍛戒腑浠诲姟鎬绘暟</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">鎬讳换鍔″紑濮�</div>
+                            <div class="summary-value datetime">{{ analysis.summary.taskStartTime$ || '--' }}</div>
+                            <div class="summary-sub">鍛戒腑浠诲姟鏈�鏃╁垱寤烘椂闂�</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">鎬讳换鍔$粨鏉�</div>
+                            <div class="summary-value datetime">{{ analysis.summary.taskEndTime$ || '--' }}</div>
+                            <div class="summary-sub">鍛戒腑浠诲姟鏈�鏅氬畬鎴愭椂闂�</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">鎬讳换鍔℃�昏�楁椂</div>
+                            <div class="summary-value">{{ formatDuration(analysis.summary.taskDurationMs) }}</div>
+                            <div class="summary-sub">鏈�鏃╁垱寤哄埌鏈�鏅氬畬鎴�</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">骞冲潎鑺傛媿</div>
+                            <div class="summary-value">{{ formatDuration(analysis.summary.avgTaskBeatDurationMs) }}</div>
+                            <div class="summary-sub">鎬讳换鍔℃�昏�楁椂 / 浠诲姟鏁�</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">骞冲潎鎬昏�楁椂</div>
+                            <div class="summary-value">{{ formatDuration(analysis.summary.avgTotalDurationMs) }}</div>
+                            <div class="summary-sub">鍒涘缓鍒板畬鎴愮殑骞冲潎鑰楁椂</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">骞冲潎绔欑偣鑰楁椂</div>
+                            <div class="summary-value">{{ formatDuration(analysis.summary.avgStationDurationMs) }}</div>
+                            <div class="summary-sub">浠呯粺璁″畬鏁撮樁娈垫暟鎹�</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">骞冲潎鍫嗗灈鏈鸿�楁椂</div>
+                            <div class="summary-value">{{ formatDuration(analysis.summary.avgCraneDurationMs) }}</div>
+                            <div class="summary-sub">浠呯粺璁″畬鏁撮樁娈垫暟鎹�</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">鏁呴殰浠诲姟鏁�</div>
+                            <div class="summary-value">{{ formatNumber(analysis.summary.faultTaskCount) }}</div>
+                            <div class="summary-sub">鍑虹幇璁惧鏁呴殰鐨勪换鍔℃暟</div>
+                        </div>
+                        <div class="summary-card">
+                            <div class="summary-label">鎬绘晠闅滆�楁椂</div>
+                            <div class="summary-value">{{ formatDuration(analysis.summary.faultDurationMs) }}</div>
+                            <div class="summary-sub">鍗曞爢鍨涙満 / 鍙屽伐浣� / RGV</div>
+                        </div>
                     </div>
-                    <div class="chart-card">
-                        <div class="chart-title">鑰楁椂瓒嬪娍</div>
-                        <div ref="trendChart" class="chart-box"></div>
-                    </div>
-                    <div class="chart-card">
-                        <div class="chart-title">鏁呴殰浠诲姟鍗犳瘮</div>
-                        <div ref="faultPieChart" class="chart-box"></div>
-                    </div>
-                    <div class="chart-card">
-                        <div class="chart-title">鏁呴殰鑰楁椂鍒嗗竷</div>
-                        <div ref="faultDurationChart" class="chart-box"></div>
+
+                    <div class="chart-grid" style="margin-top: 16px;">
+                        <div class="chart-card">
+                            <div class="chart-title">浠诲姟鑰楁椂瀵规瘮</div>
+                            <div ref="durationChart" class="chart-box"></div>
+                        </div>
+                        <div class="chart-card">
+                            <div class="chart-title">鑰楁椂瓒嬪娍</div>
+                            <div ref="trendChart" class="chart-box"></div>
+                        </div>
+                        <div class="chart-card">
+                            <div class="chart-title">鏁呴殰浠诲姟鍗犳瘮</div>
+                            <div ref="faultPieChart" class="chart-box"></div>
+                        </div>
+                        <div class="chart-card">
+                            <div class="chart-title">鏁呴殰鑰楁椂鍒嗗竷</div>
+                            <div ref="faultDurationChart" class="chart-box"></div>
+                        </div>
                     </div>
                 </div>
 
                 <div style="margin-top: 16px;">
-                    <el-table :data="analysis.detail" border stripe size="mini" max-height="360" style="width: 100%;">
+                    <div v-if="exportingPdf" ref="exportDetailRoot">
+                        <div class="export-section-title">浠诲姟鏄庣粏</div>
+                        <table ref="exportDetailTable" class="export-detail-table">
+                            <thead>
+                            <tr>
+                                <th>宸ヤ綔鍙�</th>
+                                <th>WMS浠诲姟鍙�</th>
+                                <th>浠诲姟绫诲瀷</th>
+                                <th>鏈�缁堢姸鎬�</th>
+                                <th>婧愮珯</th>
+                                <th>鐩爣绔�</th>
+                                <th>鍒涘缓鏃堕棿</th>
+                                <th>瀹屾垚鏃堕棿</th>
+                                <th>鎬昏�楁椂</th>
+                                <th>绔欑偣鑰楁椂</th>
+                                <th>鍫嗗灈鏈鸿�楁椂</th>
+                                <th>鏁呴殰娆℃暟</th>
+                                <th>鏁呴殰鑰楁椂</th>
+                                <th>鏁版嵁瀹屾暣鎬�</th>
+                            </tr>
+                            </thead>
+                            <tbody>
+                            <tr v-for="row in analysis.detail" :key="'pdf-' + row.wrkNo">
+                                <td>{{ row.wrkNo }}</td>
+                                <td>{{ row.wmsWrkNo }}</td>
+                                <td>{{ row.ioType$ }}</td>
+                                <td>{{ row.finalWrkSts$ }}</td>
+                                <td>{{ row.sourceStaNo }}</td>
+                                <td>{{ row.staNo }}</td>
+                                <td>{{ row.appeTime$ }}</td>
+                                <td>{{ row.finishTime$ }}</td>
+                                <td>{{ formatDuration(row.totalDurationMs) }}</td>
+                                <td>{{ formatDuration(row.stationDurationMs) }}</td>
+                                <td>{{ formatDuration(row.craneDurationMs) }}</td>
+                                <td>{{ row.faultCount }}</td>
+                                <td>{{ formatDuration(row.faultDurationMs) }}</td>
+                                <td>{{ row.metricCompleteness === 'COMPLETE' ? 'COMPLETE' : 'PARTIAL' }}</td>
+                            </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                    <el-table v-if="!exportingPdf" :data="analysis.detail" border stripe size="mini" max-height="360" style="width: 100%;">
                         <el-table-column prop="wrkNo" label="宸ヤ綔鍙�" width="100" align="center"></el-table-column>
                         <el-table-column prop="wmsWrkNo" label="WMS浠诲姟鍙�" min-width="150"></el-table-column>
                         <el-table-column prop="ioType$" label="浠诲姟绫诲瀷" width="90" align="center"></el-table-column>
@@ -438,6 +543,8 @@
 <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script>
 <script type="text/javascript" src="../../static/vue/element/element.js"></script>
 <script type="text/javascript" src="../../static/js/echarts/echarts.min.js"></script>
-<script type="text/javascript" src="../../static/js/wrkAnalysis/wrkAnalysis.js?v=20260322_01" charset="utf-8"></script>
+<script type="text/javascript" src="../../static/lib/pdf/html2canvas.min.js"></script>
+<script type="text/javascript" src="../../static/lib/pdf/jspdf.umd.min.js"></script>
+<script type="text/javascript" src="../../static/js/wrkAnalysis/wrkAnalysis.js?v=20260322_03" charset="utf-8"></script>
 </body>
 </html>

--
Gitblit v1.9.1