mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-01 16:32:48 +08:00
refactor(typesetting): Wave2 - 表格字号移位+画布header+对齐下拉+移除历史UI
- T3: 表格字号从设置弹框移到渲染预览header工具栏 - T4: 画布预览区添加header bar和重置对齐按钮 - T5: 对齐按钮改为select下拉,change仅CSS操作不重渲染 - T6: 移除历史记录UI(按钮/菜单/处理函数/URL变量) - CSS: alignment-toggle样式替换为alignment-select样式
This commit is contained in:
@@ -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 (中间栏代码块样式)
|
||||
仅用于编辑区中间栏, 不影响渲染页面
|
||||
|
||||
@@ -1260,18 +1260,16 @@ var PhoneImageEngine = (function () {
|
||||
var $pageNum = $('<span class="preview-thumb-page-num">' + (pageIndex + 1) + '</span>');
|
||||
$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 = $('<button class="thumb-alignment-toggle' + activeClass + '" data-page-index="' + pageIndex + '" data-page-num="' + pageNum + '">' +
|
||||
symbol +
|
||||
'</button>');
|
||||
$item.append($toggle);
|
||||
var $select = $('<select class="thumb-alignment-select" data-page-index="' + pageIndex + '" data-page-num="' + pageNum + '">' +
|
||||
'<option value="top"' + (currentAlign === 'top' ? ' selected' : '') + '>置顶</option>' +
|
||||
'<option value="center"' + (currentAlign === 'center' ? ' selected' : '') + '>居中</option>' +
|
||||
'<option value="bottom"' + (currentAlign === 'bottom' ? ' selected' : '') + '>底部</option>' +
|
||||
'</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 =====
|
||||
|
||||
@@ -215,13 +215,6 @@
|
||||
class="layui-icon layui-icon-picture"></i> 生成并保存</button>
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-primary" id="btn-export-page"><i
|
||||
class="layui-icon layui-icon-upload-circle"></i> 导出页面</button>
|
||||
<div class="more-dropdown-wrapper" style="position:relative;display:inline-block;">
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-primary" id="btn-more"><i
|
||||
class="layui-icon layui-icon-more"></i></button>
|
||||
<ul class="more-dropdown-menu" id="more-dropdown-menu" style="display:none;position:absolute;right:0;top:100%;margin-top:4px;background:#fff;border:1px solid #e8e8e8;border-radius:4px;box-shadow:0 2px 8px rgba(0,0,0,0.12);z-index:9999;min-width:130px;padding:4px 0;list-style:none;">
|
||||
<li data-action="history" style="padding:8px 16px;cursor:pointer;font-size:13px;white-space:nowrap;">历史记录</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -250,6 +243,19 @@
|
||||
<input type="number" id="font-scale-custom" min="0.5" max="2.0" step="0.1" value="1.0"
|
||||
style="width:60px;height:24px;font-size:12px;border:1px solid #d9d9d9;border-radius:3px;text-align:center;display:none;">
|
||||
<span id="font-scale-value" style="font-size:12px;color:#1890ff;min-width:32px;">1.0x</span>
|
||||
<span style="font-size:12px;color:#666;margin-left:8px;">表格字号</span>
|
||||
<select id="table-font-scale-select" style="height:26px;font-size:12px;border:1px solid #d9d9d9;border-radius:3px;padding:0 4px;">
|
||||
<option value="0.5">0.5x</option>
|
||||
<option value="0.8">0.8x</option>
|
||||
<option value="1.0" selected>1.0x</option>
|
||||
<option value="1.2">1.2x</option>
|
||||
<option value="1.5">1.5x</option>
|
||||
<option value="2.0">2.0x</option>
|
||||
<option value="custom">自定义</option>
|
||||
</select>
|
||||
<input type="number" id="table-font-scale-custom" min="0.5" max="2.0" step="0.1" value="1.0"
|
||||
style="width:60px;height:24px;font-size:12px;border:1px solid #d9d9d9;border-radius:3px;text-align:center;display:none;">
|
||||
<span id="table-font-scale-value" style="font-size:12px;color:#1890ff;min-width:32px;">1.0x</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="render-preview"></div>
|
||||
@@ -257,6 +263,12 @@
|
||||
|
||||
<!-- 右侧:分页排版预览 -->
|
||||
<div class="paginated-preview-area">
|
||||
<div class="preview-header">
|
||||
<span>画布预览</span>
|
||||
<div style="display:inline-flex;align-items:center;gap:8px;float:right;">
|
||||
<button id="btn-reset-alignments" type="button" style="height:26px;font-size:12px;border:1px solid #d9d9d9;border-radius:3px;padding:0 8px;cursor:pointer;background:#fff;">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-thumb-zone">
|
||||
<div id="paginated-preview" class="preview-thumbnails"></div>
|
||||
</div>
|
||||
@@ -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 = '<div class="settings-form" style="padding:20px 20px 0;">';
|
||||
@@ -537,27 +624,13 @@
|
||||
settingsHtml += '<input type="text" name="s_watermark" value="' + (currentConfig.watermark || '') + '" placeholder="可选水印文字" class="layui-input">';
|
||||
settingsHtml += '</div>';
|
||||
settingsHtml += '</div>';
|
||||
settingsHtml += '<div class="layui-form-item">';
|
||||
settingsHtml += '<label class="layui-form-label">表格字号</label>';
|
||||
settingsHtml += '<div class="layui-input-block">';
|
||||
settingsHtml += '<select name="s_table_font_scale">';
|
||||
var tblScaleVal = currentConfig.tableFontScale || 1;
|
||||
var tblPresets = [0.5, 0.8, 1.0, 1.2, 1.5, 2.0];
|
||||
var tblIsPreset = tblPresets.indexOf(tblScaleVal) !== -1;
|
||||
for (var pi = 0; pi < tblPresets.length; pi++) {
|
||||
settingsHtml += '<option value="' + tblPresets[pi] + '"' + (tblScaleVal === tblPresets[pi] ? ' selected' : '') + '>' + tblPresets[pi] + 'x</option>';
|
||||
}
|
||||
settingsHtml += '<option value="custom"' + (!tblIsPreset ? ' selected' : '') + '>自定义</option>';
|
||||
settingsHtml += '</select>';
|
||||
settingsHtml += '</div>';
|
||||
settingsHtml += '</div>';
|
||||
settingsHtml += '</form>';
|
||||
settingsHtml += '</div>';
|
||||
|
||||
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 = $('<button type="button" id="btn-history" style="display:none;"></button>');
|
||||
$('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 = '<div style="padding:15px;max-height:320px;overflow-y:auto;">';
|
||||
html += '<table class="layui-table" lay-skin="line" style="margin:0;">';
|
||||
html += '<colgroup><col width="150"><col width="70"><col width="70"><col width="80"></colgroup>';
|
||||
html += '<thead><tr><th>时间</th><th>状态</th><th>页数</th><th>操作</th></tr></thead>';
|
||||
html += '<tbody>';
|
||||
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 += '<tr>';
|
||||
html += '<td style="font-size:12px;">' + timeStr + '</td>';
|
||||
html += '<td>' + statusText + '</td>';
|
||||
html += '<td>' + (item.page_count || '-') + '</td>';
|
||||
html += '<td><button type="button" class="layui-btn layui-btn-xs layui-btn-normal btn-load-history" data-id="' + item.id + '">加载</button></td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</tbody></table></div>';
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user