diff --git a/src/static/app.js b/src/static/app.js new file mode 100644 index 0000000..7f89de3 --- /dev/null +++ b/src/static/app.js @@ -0,0 +1,227 @@ +// 全局状态 +let currentTemplateId = null; +let editor = null; +let templates = []; + +// 初始化 +document.addEventListener('DOMContentLoaded', () => { + initEditor(); + loadTemplates(); + checkPrinterStatus(); + bindEvents(); + setInterval(checkPrinterStatus, 5000); +}); + +function initEditor() { + editor = CodeMirror.fromTextArea(document.getElementById('yamlEditor'), { + mode: 'yaml', + theme: 'default', + lineNumbers: true, + indentUnit: 2, + tabSize: 2, + lineWrapping: true + }); + editor.on('change', debounce(updatePreview, 500)); +} + +function debounce(fn, delay) { + let timeout; + return (...args) => { + clearTimeout(timeout); + timeout = setTimeout(() => fn(...args), delay); + }; +} + +async function loadTemplates() { + try { + const res = await fetch('/api/templates'); + const data = await res.json(); + if (data.success) { + templates = data.templates; + renderTemplateList(); + } + } catch (err) { + console.error('Failed to load templates:', err); + } +} + +function renderTemplateList() { + const list = document.getElementById('templateList'); + list.innerHTML = ''; + templates.forEach(t => { + const li = document.createElement('li'); + li.textContent = t.name; + li.dataset.id = t.id; + if (t.id === currentTemplateId) li.classList.add('active'); + li.addEventListener('click', () => loadTemplate(t.id)); + list.appendChild(li); + }); +} + +async function loadTemplate(id) { + try { + const res = await fetch(`/api/templates/${id}`); + const data = await res.json(); + if (data.success) { + currentTemplateId = id; + document.getElementById('templateName').value = data.template.name; + const yaml = jsyaml.dump(data.template.config || data.template); + editor.setValue(yaml); + renderTemplateList(); + updatePreview(); + } + } catch (err) { + console.error('Failed to load template:', err); + } +} + +function updatePreview() { + try { + const yaml = editor.getValue(); + if (!yaml.trim()) { + document.getElementById('receiptPreview').innerHTML = ''; + return; + } + const config = jsyaml.load(yaml); + const testData = getTestData(); + const html = renderToHTML(config, testData); + document.getElementById('receiptPreview').innerHTML = html; + } catch (err) { + console.log('YAML parse error:', err); + } +} + +function renderToHTML(config, data) { + if (!config.blocks || !Array.isArray(config.blocks)) { + return '
配置无效
'; + } + let html = ''; + for (const block of config.blocks) { + html += renderBlockToHTML(block, data); + } + return html; +} + +function renderBlockToHTML(block, data) { + const style = []; + if (block.bold) style.push('text-bold'); + if (block.fontSize === 'small') style.push('text-small'); + if (block.fontSize === 'large') style.push('text-large'); + if (block.fontSize === 'xlarge') style.push('text-xlarge'); + const align = block.align || 'left'; + style.push(`text-${align}`); + + switch (block.type) { + case 'text': { + const content = Mustache.render(block.content, data); + return `