feat(phone-image): fontSize滑块生效、水印渲染、保存大小检查和空内容提示

T5: 通过JS setProperty动态设置--pi-font-size-base让fontSize滑块真正改变渲染字号,
    修复h4标题不使用CSS变量避免被影响
T6: 在封面页/内容页/尾页生成函数中添加水印HTML,CSS添加.page-watermark样式
T7: saveImages添加16MB大小检查,render添加空内容检测提示,
    doCapturePages错误路径添加staging清理
This commit is contained in:
augushong
2026-05-07 21:39:26 +08:00
parent 9aacfab11d
commit 491a71bd44
2 changed files with 53 additions and 1 deletions

View File

@@ -61,6 +61,17 @@
position: relative;
}
/* 水印 - 位于每页右下角的半透明文字 */
.page-watermark {
position: absolute;
bottom: 60px;
right: 20px;
font-size: 12px;
color: rgba(0, 0, 0, 0.3);
pointer-events: none;
white-space: nowrap;
}
/* ============================================
Size Variants
两种主流手机图片尺寸
@@ -255,7 +266,7 @@
}
.page-content h4 {
font-size: var(--pi-font-size-base);
font-size: 14px;
font-weight: bold;
margin-top: var(--pi-spacing-sm);
margin-bottom: 5px;

View File

@@ -145,12 +145,23 @@ var PhoneImageEngine = (function () {
var cleanHtml = preprocessContent(postData.content_html);
var blocks = parseHtmlToBlocks(cleanHtml);
// 动态设置字号CSS变量让fontSize滑块真正生效
var effectiveFontSize = parseInt(config.fontSize, 10) || 14;
document.documentElement.style.setProperty('--pi-font-size-base', effectiveFontSize + 'px');
// 缓存清理:如果缓存条目过多则清空,防止内存膨胀
var cacheKeys = Object.keys(convertedBlockCache);
if (cacheKeys.length > blocks.length * 3) {
convertedBlockCache = {};
}
// 空内容检测blocks 为空时直接提示,不进入渲染流程
if (blocks.length === 0) {
$('#paginated-preview').html('<div style="text-align:center;padding:60px 20px;color:#999;">文章正文内容为空</div>');
render._locked = false;
return deferred.resolve([]).promise();
}
// 先渲染内容流(DOM) - 用于实测高度
renderContentFlow(blocks);
@@ -681,6 +692,11 @@ var PhoneImageEngine = (function () {
html += '<div class="cover-decor-line cover-decor-bottom"></div>';
}
// 水印
if (config.watermark) {
html += '<div class="page-watermark">' + escapeHtml(config.watermark) + '</div>';
}
html += '</div>';
return { type: 'cover', html: html };
@@ -717,6 +733,11 @@ var PhoneImageEngine = (function () {
html += '<span>' + pageNum + '</span>';
html += '</div>';
// 水印
if (config.watermark) {
html += '<div class="page-watermark">' + escapeHtml(config.watermark) + '</div>';
}
html += '</div>';
return { type: 'content', html: html, pageNum: pageNum };
}
@@ -740,6 +761,12 @@ var PhoneImageEngine = (function () {
html += ' | ' + escapeHtml(postData.author_name);
}
html += '</div>';
// 水印
if (config.watermark) {
html += '<div class="page-watermark">' + escapeHtml(config.watermark) + '</div>';
}
html += '</div>';
return { type: 'summary', html: html };
@@ -944,6 +971,7 @@ var PhoneImageEngine = (function () {
}
onDone();
}).catch(function (err) {
$staging.empty();
$staging.css({ visibility: 'hidden' });
deferred.reject('截图失败: ' + err);
});
@@ -1297,6 +1325,19 @@ var PhoneImageEngine = (function () {
pagesData.push(canvases[i].toDataURL('image/jpeg', 0.92));
}
// 检查数据总大小,防止超大文章导致请求失败
var totalSize = 0;
for (var i = 0; i < pagesData.length; i++) {
if (pagesData[i]) {
totalSize += pagesData[i].length;
}
}
if (totalSize > 16 * 1024 * 1024) {
layer.msg('数据量过大超过16MB请减少内容或联系管理员');
deferred.reject('数据量过大超过16MB');
return;
}
$.ajax({
url: '/index.php/admin/post/savePostOutput',
type: 'POST',