/** localStorage 存储前缀,用于模板覆盖数据的 key */ const OVERRIDE_PREFIX = 'mope_template_override:'; /** * 深拷贝对象 * 使用 JSON 序列化/反序列化实现简单深拷贝, * 适用于纯数据的配置对象(不含函数、循环引用等)。 */ export function clone(value) { return JSON.parse(JSON.stringify(value)); } /** * 从后端加载模板索引列表 * @returns {Promise} 模板摘要数组 [{ template_id, template_name, file }] */ export async function loadTemplateIndex() { const response = await fetch('https://ch1.b.uat.4.cn/zncmweb/templates/index.json'); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); return data.templates || []; } /** * 加载完整模板数据 * 优先使用 localStorage 中的用户覆盖版本, * 否则从后端静态文件加载。 * * @param {string|Object} metaOrId - 模板 ID 字符串或包含 template_id/file 的元数据对象 * @returns {Promise} 完整模板对象 */ export async function loadTemplateByMeta(metaOrId) { const templateId = typeof metaOrId === 'string' ? metaOrId : metaOrId?.template_id; const file = typeof metaOrId === 'string' ? `/templates/${templateId}.json` : metaOrId?.file; const response = await fetch(file || `/templates/${templateId}.json`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const template = await response.json(); const override = getTemplateOverride(template.template_id || templateId); return override ? clone(override) : template; } /** * 加载原始模板(忽略用户覆盖) * @param {string|Object} metaOrId - 模板标识 * @returns {Promise} 后端静态模板 */ export async function loadOriginalTemplate(metaOrId) { const templateId = typeof metaOrId === 'string' ? metaOrId : metaOrId?.template_id; const file = typeof metaOrId === 'string' ? `/templates/${templateId}.json` : metaOrId?.file; const response = await fetch(file || `/templates/${templateId}.json`); if (!response.ok) throw new Error(`HTTP ${response.status}`); return response.json(); } /** * 获取用户在 localStorage 中保存的模板覆盖数据 * @param {string} templateId - 模板 ID * @returns {Object|null} 覆盖的模板对象,未覆盖时返回 null */ export function getTemplateOverride(templateId) { if (!templateId) return null; try { const raw = localStorage.getItem(`${OVERRIDE_PREFIX}${templateId}`); return raw ? JSON.parse(raw) : null; } catch { return null; } } /** * 判断指定模板是否已被用户覆盖修改 * @param {string} templateId - 模板 ID * @returns {boolean} */ export function hasTemplateOverride(templateId) { return Boolean(getTemplateOverride(templateId)); } /** * 保存模板覆盖到 localStorage * @param {string} templateId - 模板 ID * @param {Object} template - 修改后的模板对象 */ export function saveTemplateOverride(templateId, template) { if (!templateId) throw new Error('缺少 template_id'); localStorage.setItem(`${OVERRIDE_PREFIX}${templateId}`, JSON.stringify(template)); } /** * 清除指定模板的覆盖数据,恢复为后端原始版本 * @param {string} templateId - 模板 ID */ export function clearTemplateOverride(templateId) { if (!templateId) return; localStorage.removeItem(`${OVERRIDE_PREFIX}${templateId}`); }