From a1dbfbc97d7e451701922e08e47ab835b3a6adb7 Mon Sep 17 00:00:00 2001 From: augushong Date: Fri, 15 May 2026 22:09:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(phoneimage):=20=E6=8E=A5=E5=85=A5=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E7=AE=A1=E7=BA=BF=E9=80=90=E9=A1=B5=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/static/js/phone-image.js | 24 ++++++++++++++++++++---- view/admin/post/phone_image.html | 3 --- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/public/static/js/phone-image.js b/public/static/js/phone-image.js index fe115e6..620c53a 100644 --- a/public/static/js/phone-image.js +++ b/public/static/js/phone-image.js @@ -177,10 +177,12 @@ var PhoneImageEngine = (function () { // 防止并发渲染 if (render._locked) { // 标记有待处理的渲染请求,当前渲染完成后会自动重试 + PhoneImageLogPanel.log('渲染进行中,跳过本次请求', 'warn'); render._pending = true; return deferred.reject('rendering').promise(); } render._locked = true; + PhoneImageLogPanel.log('开始渲染...', 'info'); pages = []; var sizeConfig = config.sizes[config.size] || config.sizes.xiaohongshu; @@ -189,12 +191,15 @@ var PhoneImageEngine = (function () { // 从预览区读取已预处理的内容 syncPreview(); + PhoneImageLogPanel.log('同步预览区内容', 'info'); var previewEl = document.getElementById('render-preview'); // 等待预览区内所有图片加载完成,否则 getBoundingClientRect 测高为0 + PhoneImageLogPanel.log('等待图片加载...', 'info'); waitForImages(previewEl).then(function () { var cleanHtml = previewEl ? previewEl.innerHTML : ''; var blocks = parseHtmlToBlocks(cleanHtml); + PhoneImageLogPanel.log('解析内容: ' + blocks.length + ' 个块', 'info'); // 空内容检测 if (blocks.length === 0) { @@ -205,13 +210,16 @@ var PhoneImageEngine = (function () { // 封面页 pages.push(generateCoverPage(sizeConfig)); + PhoneImageLogPanel.log('生成封面页', 'info'); // 内容分页 + PhoneImageLogPanel.log('分页计算中...', 'info'); captureEditorBlocks(cleanHtml, blocks, contentAreaHeight, sizeConfig).then(function(contentPages) { pages = pages.concat(contentPages); // 尾页 pages.push(generateSummaryPage(sizeConfig, pages.length)); + PhoneImageLogPanel.log('生成尾页', 'info'); // 页码 N/M var totalPages = pages.length; @@ -226,6 +234,7 @@ var PhoneImageEngine = (function () { // 渲染缩略图 renderThumbnails(sizeConfig).then(function() { + PhoneImageLogPanel.log('渲染完成,共 ' + pages.length + ' 页', 'success'); render._locked = false; if (render._pending) { render._pending = false; @@ -233,10 +242,12 @@ var PhoneImageEngine = (function () { } deferred.resolve(pages); }).catch(function(err) { + PhoneImageLogPanel.log('渲染失败: ' + err, 'error'); render._locked = false; deferred.reject(err); }); }).catch(function(err) { + PhoneImageLogPanel.log('分页计算失败: ' + err, 'error'); render._locked = false; deferred.reject(err); }); @@ -1034,7 +1045,7 @@ var PhoneImageEngine = (function () { * sizeConfig: 尺寸配置(用于纯图片页canvas渲染) * @returns {jQuery Deferred} resolves with array of dataURL strings or canvas objects */ - function doCapturePages(opts) { + function doCapturePages(opts, pageProgressCallback) { var deferred = $.Deferred(); ensureStaging(); @@ -1061,7 +1072,7 @@ var PhoneImageEngine = (function () { // html2canvas会跳过visibility:hidden的元素,临时切换为可见 $staging.css({ visibility: 'visible' }); // 表格和代码块已在中间栏中转为图片,无需再次转换 - runCaptureLoop($staging, opts, deferred); + runCaptureLoop($staging, opts, deferred, pageProgressCallback); }); }); @@ -1074,7 +1085,7 @@ var PhoneImageEngine = (function () { * @param {Object} opts - 截图选项 * @param {jQuery Deferred} deferred - 外部deferred */ - function runCaptureLoop($staging, opts, deferred) { + function runCaptureLoop($staging, opts, deferred, pageProgressCallback) { var $pageElems = $staging.find('.phone-image-page'); if ($pageElems.length === 0) { $staging.css({ visibility: 'hidden' }); @@ -1108,16 +1119,18 @@ var PhoneImageEngine = (function () { // 保存模式: 高质量绘制原图到canvas renderPureImageToCanvas(pureSrc, opts.sizeConfig.width, opts.sizeConfig.height).then(function (canvas) { results.push(canvas); + if (pageProgressCallback) pageProgressCallback(idx + 1, total); idx++; captureNext(); }).catch(function () { // 加载失败,回退到html2canvas - capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, function () { idx++; captureNext(); }); + capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, function () { if (pageProgressCallback) pageProgressCallback(idx + 1, total); idx++; captureNext(); }); }); return; } else { // 缩略图模式: 直接用src results.push(pureSrc); + if (pageProgressCallback) pageProgressCallback(idx + 1, total); idx++; captureNext(); return; @@ -1169,6 +1182,8 @@ var PhoneImageEngine = (function () { outputCanvas: false, quality: 0.85, sizeConfig: sizeConfig + }, function (current, total) { + PhoneImageLogPanel.log('截图: 第 ' + current + '/' + total + ' 页', 'info'); }).then(function (dataUrls) { displayThumbnails(dataUrls, sizeConfig); deferred.resolve(pages); @@ -1574,6 +1589,7 @@ var PhoneImageEngine = (function () { syncPreview: syncPreview, setPageAlignment: setPageAlignment, exportLongImage: exportLongImage, + logPanel: PhoneImageLogPanel, getContentHtml: function () { if (window.phoneImageEditor) { return window.phoneImageEditor.getHtml(); diff --git a/view/admin/post/phone_image.html b/view/admin/post/phone_image.html index 7ed1eac..b59dbdf 100644 --- a/view/admin/post/phone_image.html +++ b/view/admin/post/phone_image.html @@ -500,12 +500,9 @@ $.extend(newConfig, extraConfig); } PhoneImageEngine.updateConfig(newConfig); - var loadIdx = layer.load(); PhoneImageEngine.render().then(function (pages) { - layer.close(loadIdx); layer.msg('排版完成,共 ' + pages.length + ' 页'); }).catch(function (err) { - layer.close(loadIdx); if (err !== 'rendering') { layer.msg('渲染失败: ' + err); }