diff --git a/public/static/css/phone-image-templates.css b/public/static/css/phone-image-templates.css index bcf9e65..9df46d3 100644 --- a/public/static/css/phone-image-templates.css +++ b/public/static/css/phone-image-templates.css @@ -902,52 +902,11 @@ body > .page-header-right .layui-btn:not(.layui-btn-primary):not(.layui-btn-norm } /* ============================================ - Divider / 分割线视觉样式 (wangeditor divider) - 在编辑器中显示为分页标记提示 + Divider / 分割线样式 (wangeditor divider) + 保留 wangeditor 默认分割线样式,不覆盖 + 分割线用于标记分页位置 ============================================ */ -/* wangeditor divider 元素 — 虚线分页标记 */ -.content-flow-area [data-w-e-type="divider"], -#editor-text-area [data-w-e-type="divider"], -#editor-text-area hr.w-e-textarea-divider, -#editor-text-area hr { - border: none; - border-top: 2px dashed var(--pi-color-accent); - margin: 15px 0; - padding: 8px 0; - text-align: center; - position: relative; - height: 0; - background: transparent; - clear: both; -} - -/* 分页标记文字提示(通过 ::after 伪元素) - 注意: wangeditor divider 是 void 元素,::after 可能不生效 - 如不生效需在 JS 中插入额外 span 提示元素 */ -.content-flow-area [data-w-e-type="divider"]::after, -#editor-text-area [data-w-e-type="divider"]::after, -#editor-text-area hr.w-e-textarea-divider::after, -#editor-text-area hr::after { - content: '-- 分页标记 --'; - display: inline-block; - font-size: 12px; - color: var(--pi-color-accent); - background: #fafafa; - padding: 0 10px; - position: relative; - top: -8px; - line-height: 1.8; -} - -/* 分割线 hover 高亮(编辑态) */ -.content-flow-area [data-w-e-type="divider"]:hover, -#editor-text-area [data-w-e-type="divider"]:hover, -#editor-text-area hr.w-e-textarea-divider:hover, -#editor-text-area hr:hover { - border-color: #40a9ff; -} - /* ============================================ Settings Dialog (设置弹框表单样式) ============================================ */ diff --git a/public/static/js/phone-image.js b/public/static/js/phone-image.js index e3ebdaf..97c36bc 100644 --- a/public/static/js/phone-image.js +++ b/public/static/js/phone-image.js @@ -525,15 +525,88 @@ var PhoneImageEngine = (function () { * @param {number} pageHeight - 可用内容高度 * @returns {Array} 拆分后的块数组 */ + /** + * 将超大表格按行拆分为多个表格块 + * 保留表头(thead或第一行tr)在每个拆分后的表格中 + * @param {Object} block - 表格块 { type:'table', html, estimatedHeight } + * @param {number} pageHeight - 可用内容高度 + * @returns {Array} 拆分后的块数组 + */ + function splitTableByRows(block, pageHeight) { + var $table = $(block.html); + var $allRows = $table.find('tr'); + if ($allRows.length <= 1) return [block]; + + // 提取表头(thead 或第一行) + var $thead = $table.find('thead'); + var headerHtml = ''; + var dataStartIdx = 0; + + if ($thead.length > 0) { + headerHtml = '' + $thead.html() + ''; + dataStartIdx = 0; // 数据行从 thead 之后开始 + // 检查 tbody + var $tbody = $table.find('tbody'); + if ($tbody.length > 0) { + $allRows = $tbody.find('tr'); + } + } else { + // 第一行作为表头 + headerHtml = '' + $allRows.eq(0).html() + ''; + dataStartIdx = 1; + } + + // 估算每行高度 + var rowCount = $allRows.length - dataStartIdx; + if (rowCount <= 0) return [block]; + var perRowHeight = block.estimatedHeight / ($allRows.length); + + // 表头高度 + var headerHeight = perRowHeight; + // 每页能放的数据行数 + var rowsPerPage = Math.floor((pageHeight - headerHeight) / perRowHeight); + if (rowsPerPage < 1) rowsPerPage = 1; + + // 保留原始表格属性(class, style 等) + var tableAttrs = ''; + var attrs = $table[0].attributes; + for (var a = 0; a < attrs.length; a++) { + if (attrs[a].name !== 'class' || attrs[a].value.indexOf('w-e') === -1) { + tableAttrs += ' ' + attrs[a].name + '="' + attrs[a].value + '"'; + } + } + + var result = []; + for (var r = dataStartIdx; r < $allRows.length; r += rowsPerPage) { + var chunkHtml = ''; + chunkHtml += headerHtml; + chunkHtml += ''; + var end = Math.min(r + rowsPerPage, $allRows.length); + for (var ri = r; ri < end; ri++) { + chunkHtml += '' + $allRows.eq(ri).html() + ''; + } + chunkHtml += ''; + + var chunkRows = end - r + (headerHtml ? 1 : 0); + result.push({ + type: 'table', + html: chunkHtml, + estimatedHeight: Math.round(chunkRows * perRowHeight) + }); + } + + return result.length > 0 ? result : [block]; + } + function splitOversizedBlock(block, pageHeight) { // 图片块不拆分,保留原样(会被截断但保持完整) if (block.type === 'img') { return [block]; } - // 表格块不拆分,保留原样 + // 表格块:按行拆分 if (block.type === 'table') { - return [block]; + return splitTableByRows(block, pageHeight); } // 代码块不拆分,保留原样