diff --git a/public/static/css/phone-image-templates.css b/public/static/css/phone-image-templates.css index 0d93485..63f80c1 100644 --- a/public/static/css/phone-image-templates.css +++ b/public/static/css/phone-image-templates.css @@ -569,42 +569,26 @@ margin-top: 6px; } -.thumb-alignment-toggle { +.thumb-alignment-select { position: absolute; - top: 8px; - right: 8px; + bottom: 4px; + right: 4px; + height: 22px; + font-size: 11px; + border: 1px solid #d9d9d9; + border-radius: 3px; + padding: 0 2px; + background: #fff; + cursor: pointer; z-index: 10; opacity: 0; - width: 24px; - height: 24px; - border-radius: 4px; - background: rgba(0, 0, 0, 0.06); - display: flex; - align-items: center; - justify-content: center; - font-size: calc(14px * var(--pi-font-scale, 1)); - color: #666; - user-select: none; - border: none; - padding: 0; - cursor: pointer; transition: opacity 0.2s; } -.preview-thumb-item:hover .thumb-alignment-toggle { +.preview-thumb-item:hover .thumb-alignment-select { opacity: 1; } -.thumb-alignment-toggle:hover { - background: rgba(0, 0, 0, 0.1); -} - -.thumb-alignment-toggle.active-center { - opacity: 1; - background: rgba(24, 144, 255, 0.15); - color: #1890ff; -} - /* ============================================ Content Flow Code Blocks (中间栏代码块样式) 仅用于编辑区中间栏, 不影响渲染页面 diff --git a/public/static/js/phone-image.js b/public/static/js/phone-image.js index 6323e5e..8e26fe7 100644 --- a/public/static/js/phone-image.js +++ b/public/static/js/phone-image.js @@ -1260,18 +1260,16 @@ var PhoneImageEngine = (function () { var $pageNum = $('' + (pageIndex + 1) + ''); $item.append($pageNum); - // 对齐按钮(仅内容页) + // 对齐下拉(仅内容页) if (pageData && pageData.type === 'content') { var pageNum = pageData.pageNum || (pageIndex); var currentAlign = (config.pageAlignments && config.pageAlignments[pageNum]) || 'top'; - var isActiveCenter = currentAlign === 'center'; - var isActiveBottom = currentAlign === 'bottom'; - var activeClass = isActiveCenter ? ' active-center' : (isActiveBottom ? ' active-bottom' : ''); - var symbol = isActiveCenter ? '\u2195' : (isActiveBottom ? '\u2193' : '\u2191'); - var $toggle = $(''); - $item.append($toggle); + var $select = $(''); + $item.append($select); } $preview.append($item); @@ -1629,24 +1627,24 @@ var PhoneImageEngine = (function () { return div.innerHTML; } - // ===== 对齐按钮事件委托 ===== - $(document).on('click', '.thumb-alignment-toggle', function () { - var $btn = $(this); - var pageNum = parseInt($btn.attr('data-page-num'), 10); - var currentAlign = (config.pageAlignments && config.pageAlignments[pageNum]) || 'top'; + // ===== 对齐下拉事件委托 ===== + $(document).on('change', '.thumb-alignment-select', function () { + var $select = $(this); + var pageNum = parseInt($select.attr('data-page-num'), 10); + var align = $select.val(); - // 三态循环: top -> center -> bottom -> top - var nextAlign; - if (currentAlign === 'top') { - nextAlign = 'center'; - } else if (currentAlign === 'center') { - nextAlign = 'bottom'; + setPageAlignment(pageNum, align); + + // 仅CSS变更,不触发完整重渲染 + var $thumbItem = $select.closest('.preview-thumb-item'); + var $thumbImg = $thumbItem.find('.preview-thumb-img'); + if (align === 'center') { + $thumbImg.css({ 'align-self': 'center' }); + } else if (align === 'bottom') { + $thumbImg.css({ 'align-self': 'flex-end' }); } else { - nextAlign = 'top'; + $thumbImg.css({ 'align-self': 'flex-start' }); } - - setPageAlignment(pageNum, nextAlign); - render(); }); // ===== 公开API ===== diff --git a/view/admin/post/phone_image.html b/view/admin/post/phone_image.html index 976aeb9..1e5d263 100644 --- a/view/admin/post/phone_image.html +++ b/view/admin/post/phone_image.html @@ -215,13 +215,6 @@ class="layui-icon layui-icon-picture"> 生成并保存 -
- - -
@@ -250,6 +243,19 @@ 1.0x + 表格字号 + + + 1.0x
@@ -257,6 +263,12 @@
+
+ 画布预览 +
+ +
+
@@ -278,8 +290,6 @@ var downloadBaseUrl = '{:url("post/downloadPostOutputZip", ["id" => 0])}'; var outputViewUrl = '{:url("post/outputView", ["id" => 0])}'; var saveConfigUrl = '{:url("post/savePostOutputConfig")}'; - var historyListUrl = '{:url("post/getOutputListJson", ["id" => $post->id])}'; - var loadConfigUrl = '{:url("post/loadPostOutputConfig")}'; // 当前排版配置(从设置弹框维护) var currentConfig = { @@ -518,6 +528,83 @@ setFontScaleUI(initConfig.fontScale); } + // ========== 表格字号下拉 ========== + var $tblScaleSelect = $('#table-font-scale-select'); + var $tblScaleCustom = $('#table-font-scale-custom'); + var $tblScaleValue = $('#table-font-scale-value'); + var tblScalePresets = [0.5, 0.8, 1.0, 1.2, 1.5, 2.0]; + + function setTableFontScaleUI(val) { + if (tblScalePresets.indexOf(val) >= 0) { + $tblScaleSelect.val(String(val)); + $tblScaleCustom.hide(); + } else { + $tblScaleSelect.val('custom'); + $tblScaleCustom.val(val).show(); + } + $tblScaleValue.text(parseFloat(val).toFixed(1) + 'x'); + } + + function applyTableFontScaleValue(val) { + val = Math.max(0.5, Math.min(2.0, parseFloat(val) || 1.0)); + $tblScaleValue.text(val.toFixed(1) + 'x'); + currentConfig.tableFontScale = val; + PhoneImageEngine.updateConfig({ tableFontScale: val }); + } + + function triggerTableFontScaleSave(val) { + val = parseFloat(val); + PhoneImageLogPanel.log('表格字号调整为 ' + val.toFixed(1) + 'x', 'info'); + doRender({ tableFontScale: val }); + updateSaveState('saving'); + PhoneImageEngine.saveConfig(postData.postId, { + size: currentConfig.size, + watermark: currentConfig.watermark, + fontScale: currentConfig.fontScale || 1, + tableFontScale: currentConfig.tableFontScale || 1, + content_html: PhoneImageEngine.getContentHtml() + }, saveConfigUrl).then(function(data) { + if (data.output_id) lastOutputId = data.output_id; + PhoneImageLogPanel.log('表格字号配置已保存', 'success'); + updateSaveState('saved'); + }).catch(function(err) { + PhoneImageLogPanel.log('表格字号保存失败: ' + err, 'error'); + updateSaveState('error'); + }); + } + + $tblScaleSelect.on('change', function() { + var selected = $(this).val(); + if (selected === 'custom') { + $tblScaleCustom.show().focus(); + } else { + $tblScaleCustom.hide(); + var val = parseFloat(selected); + applyTableFontScaleValue(val); + triggerTableFontScaleSave(val); + } + }); + + $tblScaleCustom.on('input', function() { + var val = parseFloat($(this).val()); + if (!isNaN(val) && val >= 0.5 && val <= 2.0) { + applyTableFontScaleValue(val); + } + }); + + $tblScaleCustom.on('change', function() { + var val = parseFloat($(this).val()); + if (isNaN(val) || val < 0.5) val = 0.5; + if (val > 2.0) val = 2.0; + $(this).val(val); + applyTableFontScaleValue(val); + triggerTableFontScaleSave(val); + }); + + if (initConfig.tableFontScale && initConfig.tableFontScale !== 1) { + setTableFontScaleUI(initConfig.tableFontScale); + } + // ========== 设置弹框 ========== $('#btn-settings').click(function () { var settingsHtml = '
'; @@ -537,27 +624,13 @@ settingsHtml += ''; settingsHtml += '
'; settingsHtml += '
'; - settingsHtml += '
'; - settingsHtml += ''; - settingsHtml += '
'; - settingsHtml += ''; - settingsHtml += '
'; - settingsHtml += '
'; settingsHtml += ''; settingsHtml += ''; layer.open({ type: 1, title: '排版设置', - area: ['400px', '280px'], + area: ['400px', '220px'], content: settingsHtml, btn: ['确定', '取消'], success: function (layero) { @@ -566,10 +639,8 @@ yes: function (index, layero) { currentConfig.size = layero.find('[name="s_size"]').val(); currentConfig.watermark = layero.find('[name="s_watermark"]').val(); - var tblScaleSel = layero.find('[name="s_table_font_scale"]').val(); - currentConfig.tableFontScale = tblScaleSel === 'custom' ? (currentConfig.tableFontScale || 1) : parseFloat(tblScaleSel); layer.close(index); - PhoneImageLogPanel.log('应用新设置: 尺寸=' + currentConfig.size + ', 表格字号=' + (currentConfig.tableFontScale || 1) + 'x', 'info'); + PhoneImageLogPanel.log('应用新设置: 尺寸=' + currentConfig.size, 'info'); doRender(); } }); @@ -614,24 +685,14 @@ window.open(url); }); - // ========== 更多下拉菜单(纯JS实现) ========== - var $menu = $('#more-dropdown-menu'); - $('#btn-more').on('click', function(e) { - e.stopPropagation(); - $menu.toggle(); - }); - $menu.on('click', 'li', function() { - var action = $(this).data('action'); - $menu.hide(); - switch (action) { - case 'history': - $('#btn-history').trigger('click'); - break; + // ========== 重置对齐 ========== + $('#btn-reset-alignments').click(function () { + currentConfig.pageAlignments = {}; + if (typeof PhoneImageEngine !== 'undefined') { + PhoneImageEngine.updateConfig({ pageAlignments: {} }); } - }); - // 点击外部关闭 - $(document).on('click', function() { - $menu.hide(); + doRender(); + layer.msg('已重置所有页面对齐'); }); // ========== 自动保存相关函数 ========== @@ -732,109 +793,6 @@ }); }); - // ========== 历史记录(隐藏按钮,由更多菜单和设置旁入口触发) ========== - var historyBtn = $(''); - $('body').append(historyBtn); - - historyBtn.on('click', function () { - PhoneImageLogPanel.log('获取历史记录...', 'info'); - $.get(historyListUrl, function (res) { - if (res.code !== 0 || !res.data || res.data.length === 0) { - PhoneImageLogPanel.log('暂无历史记录', 'warn'); - layer.msg('暂无历史记录'); - return; - } - - var statusMap = { 0: '草稿', 1: '已生成', 2: '失败' }; - var html = '
'; - html += ''; - html += ''; - html += ''; - html += ''; - for (var i = 0; i < res.data.length; i++) { - var item = res.data[i]; - var timeStr = (item.create_time && parseInt(item.create_time, 10) > 0) ? new Date(parseInt(item.create_time, 10) * 1000).toLocaleString('zh-CN') : '-'; - var statusText = statusMap[item.status] || '未知'; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - } - html += '
时间状态页数操作
' + timeStr + '' + statusText + '' + (item.page_count || '-') + '
'; - - layer.open({ - type: 1, - title: '排版历史记录', - area: ['520px', '400px'], - content: html, - success: function (layero) { - layero.find('.btn-load-history').on('click', function () { - var outputId = $(this).data('id'); - loadFromHistory(outputId); - }); - } - }); - }).fail(function () { - PhoneImageLogPanel.log('获取历史记录失败', 'error'); - layer.msg('获取历史记录失败'); - }); - }); - - function loadFromHistory(outputId) { - PhoneImageLogPanel.log('加载历史记录配置...', 'info'); - $.get(loadConfigUrl + '?id=' + outputId, function (res) { - if (res.code !== 0 || !res.data) { - layer.msg('加载失败: ' + (res.msg || '未知错误')); - return; - } - - var cfg = res.data.config || {}; - - // 用 setHtml 将历史内容加载到 wangeditor - if (res.data.content_html && window.phoneImageEditor) { - window.phoneImageEditor.setHtml(res.data.content_html); - } - - // 构建历史配置 - var historyConfig = {}; - if (cfg.size) historyConfig.size = cfg.size; - if (cfg.watermark !== undefined) historyConfig.watermark = cfg.watermark; - if (cfg.pageAlignments) historyConfig.pageAlignments = cfg.pageAlignments; - if (cfg.fontScale !== undefined) historyConfig.fontScale = cfg.fontScale; - if (cfg.tableFontScale !== undefined) historyConfig.tableFontScale = cfg.tableFontScale; - - // 同步当前配置 - if (cfg.size) currentConfig.size = cfg.size; - if (cfg.watermark !== undefined) currentConfig.watermark = cfg.watermark; - if (cfg.fontScale !== undefined) { - currentConfig.fontScale = cfg.fontScale; - setFontScaleUI(cfg.fontScale); - } - if (cfg.tableFontScale !== undefined) { - currentConfig.tableFontScale = cfg.tableFontScale; - } - - lastOutputId = outputId; - PhoneImageLogPanel.log('历史配置已加载', 'success'); - layer.closeAll(); - - // 更新引擎配置并重新渲染 - PhoneImageEngine.updateConfig(historyConfig); - PhoneImageEngine.render().then(function (pages) { - PhoneImageLogPanel.log('历史渲染完成,共 ' + pages.length + ' 页', 'success'); - layer.msg('已加载历史配置,共 ' + pages.length + ' 页'); - }).catch(function (err) { - PhoneImageLogPanel.log('历史渲染失败: ' + err, 'error'); - if (err !== 'rendering') layer.msg('渲染失败: ' + err); - }); - }).fail(function () { - PhoneImageLogPanel.log('加载历史配置失败', 'error'); - layer.msg('加载历史配置失败'); - }); - } - // 初始渲染 doRender(); });