57 lines
2.4 KiB
JavaScript
57 lines
2.4 KiB
JavaScript
/**
|
||
* 小程序工作台功能入口下发数据的通用组装工具
|
||
* 后端 /xxx-dashboard/entries 返回扁平数组:[{ code, name, description, icon, theme, path, group_name }]
|
||
* 这里统一转换成四个工作台首页渲染用的 sections 结构:[{ key, title, items: [{ key, label, desc, icon, theme, path }] }]
|
||
* 行为字段(角标/表单预填/弹窗等)由各首页按 code 通过 decorate 回调注入,DB 只管展示与有无
|
||
*/
|
||
|
||
/** 未配置主题时的兜底配色(与各端硬编码菜单的占位灰一致) */
|
||
const FALLBACK_THEME = { bg: 'linear-gradient(135deg, #F3F4F6, #E5E7EB)', color: '#6B7280' };
|
||
|
||
/**
|
||
* 单条下发入口 → 渲染项归一化(首页 sections 与功能页常用/历史共用同一映射,保证字段一致)
|
||
* @param {Object} entry 后端下发的入口对象
|
||
* @returns {Object|null} { key, label, desc, icon, theme, path, group };非法入口返回 null
|
||
*/
|
||
export function normalizeEntry(entry) {
|
||
if (!entry || !entry.code) return null;
|
||
return {
|
||
key: entry.code,
|
||
label: entry.name || '',
|
||
desc: entry.description || '',
|
||
icon: entry.icon || 'grid-fill',
|
||
theme: entry.theme && entry.theme.bg ? entry.theme : FALLBACK_THEME,
|
||
path: entry.path || '',
|
||
group: entry.group_name || '',
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 下发入口 → sections 结构
|
||
* @param {Array} entries 后端下发的入口数组(已按后台配置排序)
|
||
* @param {Function} [decorate] 可选行为装饰回调 (item, entry) => item|null,返回 null 表示丢弃该项
|
||
* @returns {Array} sections;entries 为空/非法时返回空数组(调用方据此回落硬编码菜单)
|
||
*/
|
||
export function groupEntriesToSections(entries, decorate) {
|
||
if (!Array.isArray(entries) || entries.length === 0) return [];
|
||
const sections = [];
|
||
entries.forEach((entry) => {
|
||
let item = normalizeEntry(entry);
|
||
if (!item) return;
|
||
if (typeof decorate === 'function') {
|
||
item = decorate(item, entry);
|
||
if (!item) return;
|
||
}
|
||
const title = entry.group_name || '快捷服务';
|
||
let section = sections.find((s) => s.title === title);
|
||
if (!section) {
|
||
// key 用分组标题即可(仅作 v-for key,首个出现顺序即分组展示顺序)
|
||
section = { key: title, title, items: [] };
|
||
sections.push(section);
|
||
}
|
||
section.items.push(item);
|
||
});
|
||
// 丢弃被 decorate 全部过滤掉的空分组
|
||
return sections.filter((s) => s.items.length > 0);
|
||
}
|