UNPKG

bixi

Version:

企业级中后台前端解决方案

241 lines (214 loc) 6.95 kB
import { Inject, Injectable } from '@angular/core'; import { I18NService } from '../core/i18n/service'; import { Meta, MetaList, MetaSearchGroup, MetaSearchGroupItem } from '../interfaces'; import { META as ACMeta } from '../routes/gen/ac/meta'; import { META as AuthMeta } from '../routes/gen/auth/meta'; import { META as ComponentsMeta } from '../routes/gen/core/meta'; import { META as LabelMeta } from '../routes/gen/label/meta'; import { META as MockMeta } from '../routes/gen/mock/meta'; // import { META as LayoutMeta } from '../routes/gen/layout/meta'; import { META as DocsMeta } from '../routes/gen/docs/meta'; // import { META as ThemeMate } from '../routes/gen/theme/meta'; import { BIXI_I18N_TOKEN } from './i18n/service.type'; // const FULLMETAS: Meta[] = [DocsMeta, ComponentsMeta, LayoutMeta, AuthMeta, ThemeMate, LabelMeta, ACMeta] as any; const FULLMETAS: Meta[] = [DocsMeta, ComponentsMeta, AuthMeta, LabelMeta, ACMeta, MockMeta] as any; @Injectable({ providedIn: 'root' }) export class MetaService { private _platMenus: any[]; private _menus: any[] | null; private _type: string; next: any; prev: any; constructor(@Inject(BIXI_I18N_TOKEN) private i18n: I18NService) { // plat titles for (const g of FULLMETAS) { for (const item of g.list!) { const curTitle = item.meta![i18n.defaultLang].title; item._t = typeof curTitle !== 'string' ? Object.values(curTitle!) .map(v => v) .join('-') : curTitle; } } } private _data: any; private _isPages = false; private getCatgory(url: string) { const arr = url.split('?')[0].split('/'); if (arr.length <= 2) return false; let categoryName = arr[1].toLowerCase().trim(); let category = FULLMETAS.find(w => w.name === categoryName); if (~categoryName.indexOf('-')) { categoryName = categoryName.split('-')[0]; category = FULLMETAS.find(w => w.name === categoryName); this._isPages = !!category; } else { this._isPages = false; } return category; } private getPageName(url: string) { return url .split('?')[0] .split('/')[2] .toLowerCase() .trim(); } /** `true` 表示需要跳转404 */ set(url: string): boolean { const category = this.getCatgory(url); if (!category) return false; const name = this.getPageName(url); const data = category.list!.find(w => w.name === name) || null; if (!data) return true; this._data = { ...data.meta![this.i18n.defaultLang], ...data.meta![this.i18n.lang], i18n: data.i18n, name: data.name, module_name: category.module || '', github: category.github, list: category.list }; // fix title if (typeof this._data.title === 'object') { this._data.title = this._data.title[this.i18n.lang] || this._data.title[this.i18n.defaultLang]; } this.refPage(url); return false; } get item() { return this._data || {}; } get github(): string { return this._data.github; } get data(): MetaList[] { return this._data.list; } get isPages() { return this._isPages; } get menus() { return this._menus; } get type() { return this._type; } clearMenu() { this._menus = null; } private getType(url: string): string { const category = this.getCatgory(url); return category ? url .split('?')[0] .split('/')[1] .toLowerCase() .split('-')[0] : ''; } refMenu(url: string) { if (!this.menus) { this.genMenus(url); return; } const curType = this.getType(url); if (curType && this._type !== curType) { this.genMenus(url); return; } } genMenus(url: string): void { const category = this.getCatgory(url); if (!category) return; // todo: support level 2 const group: any[] = category.types!.map((item: any, index: number) => { return { index, title: item[this.i18n.lang] || item[this.i18n.defaultLang], list: [] }; }); category.list!.forEach((item: any) => { const meta = item.meta[this.i18n.lang] || item.meta[this.i18n.defaultLang]; let typeIdx = category.types!.findIndex(w => w['zh-CN'] === meta.type || w['en-US'] === meta.type); if (typeIdx === -1) typeIdx = 0; let groupItem = group.find(w => w.index === typeIdx); if (!groupItem) { groupItem = { index: typeIdx, title: category.types![typeIdx][this.i18n.lang] || category.types![typeIdx][this.i18n.defaultLang], list: [] }; group.push(groupItem); } const entry: any = { url: (meta.url || item.route || `/${category.name}/${item.name}`) + `/${this.i18n.zone}`, title: this.i18n.get(meta.title), subtitle: meta.subtitle, order: item.order, hot: typeof meta.hot === 'boolean' ? meta.hot : false, lib: typeof item.lib === 'boolean' ? item.lib : false }; groupItem.list.push(entry); }); this._platMenus = []; this._menus = group .filter((item: any) => Array.isArray(item.list) && item.list.length > 0) .map((item: any) => { if (item.list[0].order === -1) { item.list.sort((a: any, b: any) => a.title.toLowerCase().localeCompare(b.title.toLowerCase())); } else { item.list.sort((a: any, b: any) => a.order - b.order); } this._platMenus = this._platMenus.concat(item.list); return item; }) .filter((item: any) => item.list.length); } getPathByUrl(url: string): any { url = url.split('=')[0].split('?')[0]; let ret: any; (this._menus || []).forEach((cat: any) => { if (ret) return; ret = cat.list.find((i: any) => i.url === url); }); return ret; } private refPage(url: string) { this.next = null; this.prev = null; if (!this._menus) this.genMenus(url); const idx = this._platMenus.findIndex(w => w.url === url); if (idx === -1) return; if (idx > 0) this.prev = this._platMenus[idx - 1]; if (idx + 1 <= this._platMenus.length) this.next = this._platMenus[idx + 1]; } search(q: string, childrenMax = 5): MetaSearchGroup[] { const zone = this.i18n.zone; const res: MetaSearchGroup[] = []; for (const g of FULLMETAS) { const type = g.name!.toLowerCase(); const children: MetaSearchGroupItem[] = g .list!.filter(w => w._t.includes(q)) .map(item => { return { title: item._t, name: item.name, url: (item.route || `/${type}/${item.name}`) + `/${zone}` }; }); if (children != null && children.length) { res.push({ title: g.name, type, children: children.slice(0, childrenMax) }); } } return res; } }