(function () { 'use strict'; var Api = function () { return window.AdminApi; }; var Ui = function () { return window.AdminUi; }; var I = function () { return window.AdminI18n; }; var Form = function () { return window.AdminForm; }; function activeBadge(v) { var on = v === true || parseInt(v, 10) === 1; return I().badgeStatus(on ? 'active' : 'disabled'); } function typeLabel(type) { return Number(type) === 2 ? '双面' : '单面'; } function formatBytes(n) { n = parseInt(n, 10) || 0; if (!n) return '—'; if (n < 1024) return n + ' B'; if (n < 1048576) return (n / 1024).toFixed(1) + ' KB'; return (n / 1048576).toFixed(1) + ' MB'; } function readFileText(input) { return new Promise(function (resolve, reject) { var file = input && input.files && input.files[0]; if (!file) { reject(new Error('no_file')); return; } var reader = new FileReader(); reader.onload = function () { resolve(String(reader.result || '')); }; reader.onerror = function () { reject(new Error('read_failed')); }; reader.readAsText(file, 'UTF-8'); }); } function defaultNameFromFile(input) { var file = input && input.files && input.files[0]; if (!file) return ''; return file.name.replace(/\.soon$/i, '').replace(/[_-]+/g, ' ').trim(); } function uploadFields(required) { return Form().panel('模板文件', Form().field('选择 .soon 文件', '' + (required ? '' : '

留空则不替换已有文件

'), required ? '须为有效的 .soon JSON 文件' : '') ); } function metaFields(plan) { plan = plan || {}; return Form().panel('展示设置', Form().field('名称', Form().input('tplName', { value: plan.name || '' })) + '
' + Form().field('排序', Form().input('tplSort', { type: 'number', value: plan.sort_order != null ? plan.sort_order : 0 })) + Form().field('类型', '') + '
' + '' ); } function openCreateModal() { var form = '
' + uploadFields(true) + metaFields() + Form().actions('上传', 'adminModalSave') + '
'; Ui().openFormModal('上传模板', form, function () { var nameEl = Ui().el('tplName'); var fileEl = Ui().el('tplFile'); var name = nameEl.value.trim() || defaultNameFromFile(fileEl); if (!name) { soonToast('请填写名称或选择文件', 'warn'); return false; } return readFileText(fileEl).then(function (content) { return Api().postJson('templates', { name: name, content: content, sort_order: parseInt(Ui().el('tplSort').value, 10) || 0, is_active: Ui().el('tplActive').checked ? 1 : 0, }).then(function (r) { if (r) { layer.closeAll(); soonToast('已上传', 'success'); render(); } }); }).catch(function (e) { if (e && e.message === 'no_file') soonToast('请选择 .soon 文件', 'warn'); else soonToast('文件读取失败', 'error'); }); }, { area: ['480px', 'auto'] }); } function openEditModal(plan) { var form = '
' + metaFields(plan) + uploadFields(false) + Form().actions('保存', 'adminModalSave') + '
'; Ui().openFormModal('编辑模板 · ' + plan.name, form, function () { var name = Ui().el('tplName').value.trim(); if (!name) { soonToast('名称不能为空', 'warn'); return false; } var body = { name: name, sort_order: parseInt(Ui().el('tplSort').value, 10) || 0, is_active: Ui().el('tplActive').checked ? 1 : 0, }; var fileEl = Ui().el('tplFile'); var hasFile = fileEl && fileEl.files && fileEl.files[0]; var save = function (content) { if (content) body.content = content; return Api().putJson('templates/' + plan.id, body).then(function (r) { if (r) { layer.closeAll(); soonToast('已保存', 'success'); render(); } }); }; if (hasFile) { return readFileText(fileEl).then(save).catch(function () { soonToast('文件读取失败', 'error'); }); } return save(null); }, { area: ['480px', 'auto'] }); } function deleteTemplate(plan) { Ui().confirm('确定删除模板「' + plan.name + '」?', function () { Api().del('templates/' + plan.id).then(function (r) { if (r) { soonToast('已删除', 'success'); render(); } }); }); } function render() { var panel = Ui().el('panel-templates'); if (!panel) return; panel.innerHTML = '
' + Ui().pageHeader('模板库', '管理首页展示的 .soon 模板(缩略图与名称轻量加载)', '') + Ui().skeletonTable() + '
'; Api().get('templates').then(function (j) { if (!j) return; var items = j.data.items || []; var rows = items.map(function (p) { return '' + p.id + '' + I().esc(p.name) + '' + typeLabel(p.type) + '' + formatBytes(p.file_size) + '' + p.sort_order + '' + (p.has_thumb ? '有' : '—') + '' + activeBadge(p.is_active) + '' + ' ' + ''; }).join(''); panel.innerHTML = '
' + Ui().pageHeader('模板库', '管理首页展示的 .soon 模板(缩略图与名称轻量加载)', '') + Ui().dataTable( ['ID', '名称', '类型', '大小', '排序', '缩略图', '状态', '操作'], rows ) + '
'; var planMap = {}; items.forEach(function (p) { planMap[p.id] = p; }); panel.querySelector('#tplCreate').onclick = openCreateModal; panel.querySelectorAll('.tpl-edit').forEach(function (btn) { btn.onclick = function () { var id = parseInt(btn.closest('tr').dataset.id, 10); if (planMap[id]) openEditModal(planMap[id]); }; }); panel.querySelectorAll('.tpl-del').forEach(function (btn) { btn.onclick = function () { var id = parseInt(btn.closest('tr').dataset.id, 10); if (planMap[id]) deleteTemplate(planMap[id]); }; }); }); } window.AdminViews = window.AdminViews || {}; window.AdminViews.templates = { render: render }; })();