From 7272158c8e133afcdf752ca09a70c0bd969d7393 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 25 三月 2026 19:57:26 +0800
Subject: [PATCH] #

---
 src/main/webapp/static/js/wrkAnalysis/wrkAnalysis.js |  116 +++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 98 insertions(+), 18 deletions(-)

diff --git a/src/main/webapp/static/js/wrkAnalysis/wrkAnalysis.js b/src/main/webapp/static/js/wrkAnalysis/wrkAnalysis.js
index b1904c5..4ea91bf 100644
--- a/src/main/webapp/static/js/wrkAnalysis/wrkAnalysis.js
+++ b/src/main/webapp/static/js/wrkAnalysis/wrkAnalysis.js
@@ -29,6 +29,12 @@
         return {
             summary: {
                 taskCount: 0,
+                taskStartTime: null,
+                taskStartTime$: "",
+                taskEndTime: null,
+                taskEndTime$: "",
+                taskDurationMs: null,
+                avgTaskBeatDurationMs: null,
                 avgTotalDurationMs: null,
                 avgStationDurationMs: null,
                 avgCraneDurationMs: null,
@@ -310,10 +316,15 @@
                     window.html2canvas(visualRoot, this.buildCaptureOptions(visualRoot)),
                     window.html2canvas(detailRoot, this.buildCaptureOptions(detailRoot))
                 ]).then(function (results) {
+                    var visualAvoidSplitBounds = self.collectAvoidSplitBounds(visualRoot, results[0], [
+                        ".quality-banner",
+                        ".chart-card"
+                    ]);
                     self.appendCanvasSlicesToPdf(pdf, results[0], {
                         margin: 8,
                         startY: 8,
-                        addNewPage: false
+                        addNewPage: false,
+                        avoidSplitBounds: visualAvoidSplitBounds
                     });
                     self.appendDetailTableToPdf(pdf, results[1], detailRoot, detailTable, 8);
                     pdf.save(self.buildPdfFileName());
@@ -354,6 +365,7 @@
                 while (renderedHeight < canvas.height) {
                     var currentPageHeightPx = Math.max(1, Math.floor((pageHeight - margin - currentY) * pxPerMm));
                     var sliceHeight = Math.min(currentPageHeightPx, canvas.height - renderedHeight);
+                    sliceHeight = this.resolveSliceHeight(renderedHeight, sliceHeight, settings.avoidSplitBounds);
                     pageCanvas.width = canvas.width;
                     pageCanvas.height = sliceHeight;
                     pageContext.fillStyle = "#ffffff";
@@ -388,6 +400,51 @@
                     renderedHeight += sliceHeight;
                     currentY = margin;
                 }
+            },
+            collectAvoidSplitBounds: function (rootElement, rootCanvas, selectors) {
+                if (!rootElement || !rootCanvas || !selectors || !selectors.length) {
+                    return [];
+                }
+                var rootRect = rootElement.getBoundingClientRect();
+                if (!rootRect.width) {
+                    return [];
+                }
+                var scale = rootCanvas.width / rootRect.width;
+                var elements = [];
+                selectors.forEach(function (selector) {
+                    Array.prototype.push.apply(elements, Array.prototype.slice.call(rootElement.querySelectorAll(selector)));
+                });
+                return elements.map(function (element) {
+                    var rect = element.getBoundingClientRect();
+                    return {
+                        top: Math.max(0, Math.round((rect.top - rootRect.top) * scale)),
+                        bottom: Math.max(0, Math.round((rect.bottom - rootRect.top) * scale))
+                    };
+                }).filter(function (item) {
+                    return item.bottom > item.top;
+                }).sort(function (a, b) {
+                    return a.top - b.top;
+                });
+            },
+            resolveSliceHeight: function (renderedHeight, desiredHeight, avoidSplitBounds) {
+                if (!avoidSplitBounds || !avoidSplitBounds.length) {
+                    return desiredHeight;
+                }
+                var sliceEnd = renderedHeight + desiredHeight;
+                var adjustedHeight = desiredHeight;
+                avoidSplitBounds.forEach(function (bound) {
+                    if (bound.top <= renderedHeight) {
+                        return;
+                    }
+                    if (bound.top >= sliceEnd || bound.bottom <= sliceEnd) {
+                        return;
+                    }
+                    var candidateHeight = bound.top - renderedHeight;
+                    if (candidateHeight > 0 && candidateHeight < adjustedHeight) {
+                        adjustedHeight = candidateHeight;
+                    }
+                });
+                return adjustedHeight > 0 ? adjustedHeight : desiredHeight;
             },
             appendDetailTableToPdf: function (pdf, rootCanvas, detailRoot, detailTable, margin) {
                 var tbody = detailTable && detailTable.tBodies && detailTable.tBodies[0];
@@ -557,7 +614,7 @@
                         }
                     },
                     legend: { data: ["绔欑偣鑰楁椂", "鍫嗗灈鏈鸿�楁椂", "鎬昏�楁椂"] },
-                    grid: { left: 50, right: 20, top: 40, bottom: 70 },
+                    grid: { left: 88, right: 20, top: 40, bottom: 70, containLabel: true },
                     xAxis: {
                         type: "category",
                         data: rows.map(function (item) { return String(item.wrkNo); }),
@@ -599,7 +656,7 @@
                         }
                     },
                     legend: { data: ["骞冲潎鎬昏�楁椂", "骞冲潎绔欑偣鑰楁椂", "骞冲潎鍫嗗灈鏈鸿�楁椂"] },
-                    grid: { left: 50, right: 20, top: 40, bottom: 70 },
+                    grid: { left: 88, right: 20, top: 40, bottom: 70, containLabel: true },
                     xAxis: {
                         type: "category",
                         data: rows.map(function (item) { return item.bucketLabel; }),
@@ -656,10 +713,14 @@
                             return lines.join("<br>");
                         }
                     },
-                    grid: { left: 50, right: 20, top: 20, bottom: 40 },
+                    grid: { left: 88, right: 20, top: 20, bottom: 68, containLabel: true },
                     xAxis: {
                         type: "category",
-                        data: rows.map(function (item) { return item.name; })
+                        data: rows.map(function (item) { return item.name; }),
+                        axisLabel: {
+                            interval: 0,
+                            rotate: rows.length > 6 ? 30 : 0
+                        }
                     },
                     yAxis: {
                         type: "value",
@@ -743,11 +804,7 @@
                 if (!isFinite(num)) {
                     return "0s";
                 }
-                var text = String(num);
-                if (text.indexOf(".") >= 0) {
-                    text = text.replace(/0+$/, "").replace(/\.$/, "");
-                }
-                return text + "s";
+                return this.formatDurationBySeconds(num);
             },
             formatDuration: function (value) {
                 if (value === null || value === undefined || value === "") {
@@ -760,17 +817,40 @@
                 if (ms < 1000) {
                     return Math.round(ms) + " ms";
                 }
-                var totalSeconds = Math.floor(ms / 1000);
-                var hours = Math.floor(totalSeconds / 3600);
-                var minutes = Math.floor((totalSeconds % 3600) / 60);
-                var seconds = totalSeconds % 60;
+                return this.formatDurationBySeconds(ms / 1000);
+            },
+            formatDurationBySeconds: function (seconds) {
+                var totalSeconds = Number(seconds || 0);
+                if (!isFinite(totalSeconds)) {
+                    return "0s";
+                }
+                var safeSeconds = Math.max(0, totalSeconds);
+                if (safeSeconds < 60) {
+                    return this.trimTrailingZeros(safeSeconds) + "s";
+                }
+                var hours = Math.floor(safeSeconds / 3600);
+                var minutes = Math.floor((safeSeconds % 3600) / 60);
+                var remainSeconds = safeSeconds - hours * 3600 - minutes * 60;
+                var secondText = this.trimTrailingZeros(remainSeconds);
                 if (hours > 0) {
-                    return hours + "h " + this.pad(minutes) + "m " + this.pad(seconds) + "s";
+                    return hours + "h" + this.pad(minutes) + "m" + this.padSeconds(secondText) + "s";
                 }
-                if (minutes > 0) {
-                    return minutes + "m " + this.pad(seconds) + "s";
+                return minutes + "m" + this.padSeconds(secondText) + "s";
+            },
+            trimTrailingZeros: function (value) {
+                var text = String(Number(Number(value).toFixed(3)));
+                if (text.indexOf(".") >= 0) {
+                    text = text.replace(/0+$/, "").replace(/\.$/, "");
                 }
-                return seconds + "s";
+                return text;
+            },
+            padSeconds: function (value) {
+                var text = String(value);
+                if (text.indexOf(".") >= 0) {
+                    var parts = text.split(".");
+                    return (parts[0].length < 2 ? "0" + parts[0] : parts[0]) + "." + parts[1];
+                }
+                return text.length < 2 ? "0" + text : text;
             }
         }
     });

--
Gitblit v1.9.1