vome-core 0.0.8 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/api/client.d.ts +32 -0
- package/dist/admin/api/client.js +1 -0
- package/dist/admin/config/plugin-dev.d.ts +30 -0
- package/dist/admin/config/plugin-dev.js +1 -0
- package/dist/admin/crud/config.d.ts +5 -0
- package/dist/admin/crud/config.js +1 -0
- package/dist/admin/crud/confirm.d.ts +11 -0
- package/dist/admin/crud/confirm.js +1 -0
- package/dist/admin/crud/dict.d.ts +3 -0
- package/dist/admin/crud/dict.js +1 -0
- package/dist/admin/crud/index.d.ts +40 -0
- package/dist/admin/crud/index.js +1 -0
- package/dist/admin/crud/key.d.ts +22 -0
- package/dist/admin/crud/key.js +1 -0
- package/dist/admin/crud/mitt.d.ts +10 -0
- package/dist/admin/crud/mitt.js +1 -0
- package/dist/admin/crud/plugins.d.ts +48 -0
- package/dist/admin/crud/plugins.js +1 -0
- package/dist/admin/crud/registry.d.ts +5 -0
- package/dist/admin/crud/registry.js +26 -0
- package/dist/admin/crud/span.d.ts +17 -0
- package/dist/admin/crud/span.js +1 -0
- package/dist/admin/crud/style.d.ts +36 -0
- package/dist/admin/crud/style.js +1 -0
- package/dist/admin/crud/useCrud.d.ts +18 -0
- package/dist/admin/crud/useCrud.js +1 -0
- package/dist/admin/crud/validate.d.ts +14 -0
- package/dist/admin/crud/validate.js +1 -0
- package/dist/admin/directives/perm.d.ts +3 -0
- package/dist/admin/directives/perm.js +1 -0
- package/dist/admin/hooks/useBrowser.d.ts +5 -0
- package/dist/admin/hooks/useBrowser.js +1 -0
- package/dist/admin/hooks/useUpload.d.ts +8 -0
- package/dist/admin/hooks/useUpload.js +1 -0
- package/dist/admin/hooks/useVome.d.ts +8 -0
- package/dist/admin/hooks/useVome.js +1 -0
- package/dist/admin/index.d.ts +26 -0
- package/dist/admin/index.js +1 -0
- package/dist/admin/lib/browser.d.ts +3 -0
- package/dist/admin/lib/browser.js +1 -0
- package/dist/admin/lib/cn.d.ts +2 -0
- package/dist/admin/lib/cn.js +1 -0
- package/dist/admin/lib/dialog-float.d.ts +4 -0
- package/dist/admin/lib/dialog-float.js +1 -0
- package/dist/admin/lib/eps.d.ts +11 -0
- package/dist/admin/lib/eps.js +1 -0
- package/dist/admin/lib/menu.d.ts +2 -0
- package/dist/admin/lib/menu.js +1 -0
- package/dist/admin/lib/module.d.ts +21 -0
- package/dist/admin/lib/module.js +1 -0
- package/dist/admin/lib/tree.d.ts +2 -0
- package/dist/admin/lib/tree.js +1 -0
- package/dist/admin/lib/upload.d.ts +13 -0
- package/dist/admin/lib/upload.js +1 -0
- package/dist/admin/router/index.d.ts +3 -0
- package/dist/admin/router/index.js +1 -0
- package/dist/admin/router/menu-routes.d.ts +7 -0
- package/dist/admin/router/menu-routes.js +1 -0
- package/dist/admin/service/base.d.ts +27 -0
- package/dist/admin/service/base.js +1 -0
- package/dist/admin/service/index.d.ts +15 -0
- package/dist/admin/service/index.js +1 -0
- package/dist/admin/stores/app.d.ts +1 -0
- package/dist/admin/stores/app.js +1 -0
- package/dist/admin/stores/tags.d.ts +1 -0
- package/dist/admin/stores/tags.js +1 -0
- package/dist/admin/stores/user.d.ts +1 -0
- package/dist/admin/stores/user.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -236
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -3261
- package/dist/shared/index.js +1 -0
- package/dist/shared/tree.d.ts +18 -0
- package/dist/shared/tree.js +1 -0
- package/package.json +13 -10
- package/src/shared/tree.d.ts +18 -0
- package/typings/admin/base/auth.d.ts +20 -0
- package/typings/admin/base/permission.d.ts +19 -0
- package/typings/admin/comm/crud.d.ts +282 -0
- package/typings/admin/comm/request.d.ts +11 -0
- package/typings/admin/comm/service.d.ts +40 -0
- package/typings/admin/comm/upload.d.ts +26 -0
- package/typings/admin/vome/browser.d.ts +10 -0
- package/typings/admin/vome/module.d.ts +13 -0
- package/src/admin/api/client.ts +0 -184
- package/src/admin/config/plugin-dev.ts +0 -31
- package/src/admin/crud/config.ts +0 -38
- package/src/admin/crud/confirm.ts +0 -135
- package/src/admin/crud/dict.ts +0 -49
- package/src/admin/crud/index.ts +0 -79
- package/src/admin/crud/key.ts +0 -47
- package/src/admin/crud/mitt.ts +0 -27
- package/src/admin/crud/plugins.ts +0 -298
- package/src/admin/crud/registry.ts +0 -45
- package/src/admin/crud/span.ts +0 -48
- package/src/admin/crud/style.ts +0 -112
- package/src/admin/crud/useCrud.ts +0 -81
- package/src/admin/crud/validate.ts +0 -109
- package/src/admin/directives/perm.ts +0 -18
- package/src/admin/hooks/useBrowser.ts +0 -27
- package/src/admin/hooks/useUpload.ts +0 -82
- package/src/admin/hooks/useVome.ts +0 -13
- package/src/admin/index.ts +0 -59
- package/src/admin/lib/browser.ts +0 -28
- package/src/admin/lib/cn.ts +0 -7
- package/src/admin/lib/dialog-float.ts +0 -14
- package/src/admin/lib/eps.ts +0 -44
- package/src/admin/lib/menu.ts +0 -14
- package/src/admin/lib/module.ts +0 -112
- package/src/admin/lib/tree.ts +0 -2
- package/src/admin/lib/upload.ts +0 -102
- package/src/admin/router/index.ts +0 -68
- package/src/admin/router/menu-routes.ts +0 -126
- package/src/admin/service/base.ts +0 -96
- package/src/admin/service/index.ts +0 -378
- package/src/admin/stores/app.ts +0 -30
- package/src/admin/stores/tags.ts +0 -73
- package/src/admin/stores/user.ts +0 -52
- /package/{src → dist}/admin/components/vm-aside.vue +0 -0
- /package/{src → dist}/admin/components/vm-auto-perm-dialog.vue +0 -0
- /package/{src → dist}/admin/components/vm-check-tree.vue +0 -0
- /package/{src → dist}/admin/components/vm-dept-tree.vue +0 -0
- /package/{src → dist}/admin/components/vm-empty.vue +0 -0
- /package/{src → dist}/admin/components/vm-eps-perm-picker.vue +0 -0
- /package/{src → dist}/admin/components/vm-group-cascader.vue +0 -0
- /package/{src → dist}/admin/components/vm-icon-picker.vue +0 -0
- /package/{src → dist}/admin/components/vm-markdown.vue +0 -0
- /package/{src → dist}/admin/components/vm-ri-icon.vue +0 -0
- /package/{src → dist}/admin/components/vm-role-picker.vue +0 -0
- /package/{src → dist}/admin/components/vm-view-path-picker.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-column-custom.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-context-menu.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-date-picker.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-date-range.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-date-text.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-dict-tag.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-file-icon.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-multi-select.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-number-range.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-radio.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-select.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-switch.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-tree-select.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-upload-item.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-upload.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-user-select.vue +0 -0
- /package/{src → dist}/admin/crud/vm-add-btn.vue +0 -0
- /package/{src → dist}/admin/crud/vm-adv-search.vue +0 -0
- /package/{src → dist}/admin/crud/vm-crud.vue +0 -0
- /package/{src → dist}/admin/crud/vm-dialog.vue +0 -0
- /package/{src → dist}/admin/crud/vm-flex1.vue +0 -0
- /package/{src → dist}/admin/crud/vm-form.vue +0 -0
- /package/{src → dist}/admin/crud/vm-multi-delete-btn.vue +0 -0
- /package/{src → dist}/admin/crud/vm-pagination.vue +0 -0
- /package/{src → dist}/admin/crud/vm-refresh-btn.vue +0 -0
- /package/{src → dist}/admin/crud/vm-row.vue +0 -0
- /package/{src → dist}/admin/crud/vm-search-key.vue +0 -0
- /package/{src → dist}/admin/crud/vm-search.vue +0 -0
- /package/{src → dist}/admin/crud/vm-table.vue +0 -0
- /package/{src → dist}/admin/crud/vm-toolbar.vue +0 -0
- /package/{src → dist}/admin/crud/vm-upsert.vue +0 -0
- /package/{src → dist}/admin/data/remixicon-all.json +0 -0
- /package/{src → dist}/admin/env.d.ts +0 -0
- /package/{src → dist}/admin/static/fileicon/demo.css +0 -0
- /package/{src → dist}/admin/static/fileicon/demo_index.html +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.css +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.js +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.json +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.ttf +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.woff +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.woff2 +0 -0
- /package/{src → dist}/admin/static/scarce//344/270/213/350/275/275/345/244/261/350/264/245.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/224/257/344/273/230/346/210/220/345/212/237.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/344/274/230/346/203/240/345/210/270.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/206/205/345/256/271.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/217/221/347/245/250.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/233/276/347/211/207.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/234/260/345/235/200.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/272/227/351/223/272.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/216/250/351/200/201.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/220/234/347/264/242/347/273/223/346/236/234.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/224/266/350/227/217.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/225/260/346/215/256.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/235/203/351/231/220.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/266/210/346/201/257.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/347/244/274/347/211/251.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/347/247/257/345/210/206.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/347/275/221/347/273/234.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/350/247/206/351/242/221.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/350/256/242/345/215/225.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/350/257/204/350/256/272.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/351/205/215/351/200/201.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/351/223/266/350/241/214/345/215/241.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/351/237/263/344/271/220.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//351/241/265/351/235/242/344/270/215/345/255/230/345/234/250.svg" +0 -0
- /package/{src → dist}/admin/styles/base.css +0 -0
- /package/{src → dist}/admin/tsconfig.json +0 -0
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import type { Router, RouteRecordRaw } from 'vue-router'
|
|
2
|
-
import { defineComponent, h } from 'vue'
|
|
3
|
-
import { resolveView, viewPathToName } from '../lib/module'
|
|
4
|
-
import MissingView from '#vome-host/pages/missing/index.vue'
|
|
5
|
-
import MicroAppView from '#vome-host/pages/micro/index.vue'
|
|
6
|
-
|
|
7
|
-
/** 已挂载的动态菜单路由名 menu-${id} */
|
|
8
|
-
const addedNames = new Set<string>()
|
|
9
|
-
|
|
10
|
-
function isMicroMenu(m: MenuTreeNode) {
|
|
11
|
-
return Boolean(m.appKey && m.router)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function walk(nodes: MenuTreeNode[], out: MenuTreeNode[]) {
|
|
15
|
-
for (const n of nodes) {
|
|
16
|
-
if (Number(n.type) === 1 && n.router) out.push(n)
|
|
17
|
-
if (n.children?.length) walk(n.children, out)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function missingView(viewPath: string) {
|
|
22
|
-
return defineComponent({
|
|
23
|
-
name: 'MissingViewPage',
|
|
24
|
-
setup() {
|
|
25
|
-
return () => h(MissingView, { path: viewPath })
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function routeNameOf(id: number | string) {
|
|
31
|
-
return `menu-${id}`
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function buildRoute(item: MenuTreeNode): RouteRecordRaw {
|
|
35
|
-
const full = item.router!
|
|
36
|
-
const childPath = full.replace(/^\//, '')
|
|
37
|
-
let component: RouteRecordRaw['component']
|
|
38
|
-
const componentName = viewPathToName(item.viewPath)
|
|
39
|
-
const meta: Record<string, unknown> = {
|
|
40
|
-
title: item.name,
|
|
41
|
-
keepAlive: item.keepAlive !== false,
|
|
42
|
-
viewPath: item.viewPath,
|
|
43
|
-
perms: item.perms,
|
|
44
|
-
componentName,
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (isMicroMenu(item)) {
|
|
48
|
-
component = MicroAppView
|
|
49
|
-
meta.appKey = item.appKey
|
|
50
|
-
meta.componentName = `micro-${item.appKey}`
|
|
51
|
-
meta.keepAlive = false
|
|
52
|
-
} else if (item.viewPath) {
|
|
53
|
-
const loader = resolveView(item.viewPath)
|
|
54
|
-
component = loader || missingView(item.viewPath)
|
|
55
|
-
} else {
|
|
56
|
-
component = missingView(full)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
path: childPath,
|
|
61
|
-
name: routeNameOf(item.id),
|
|
62
|
-
component,
|
|
63
|
-
meta,
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** 根据权限菜单动态挂载:viewPath 本地模块 / appKey 微应用(仅补新增) */
|
|
68
|
-
export async function ensureMenuRoutes(router: Router, menus: MenuTreeNode[]) {
|
|
69
|
-
const items: MenuTreeNode[] = []
|
|
70
|
-
walk(menus, items)
|
|
71
|
-
|
|
72
|
-
for (const item of items) {
|
|
73
|
-
const name = routeNameOf(item.id)
|
|
74
|
-
if (addedNames.has(name)) continue
|
|
75
|
-
addedNames.add(name)
|
|
76
|
-
router.addRoute('layout', buildRoute(item))
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** 全量同步:删旧补新,菜单改名/改路由/显隐后侧栏与路由一致 */
|
|
81
|
-
export async function syncMenuRoutes(router: Router, menus: MenuTreeNode[]) {
|
|
82
|
-
const items: MenuTreeNode[] = []
|
|
83
|
-
walk(menus, items)
|
|
84
|
-
const nextNames = new Set(items.map((i) => routeNameOf(i.id)))
|
|
85
|
-
|
|
86
|
-
for (const name of [...addedNames]) {
|
|
87
|
-
if (!nextNames.has(name)) {
|
|
88
|
-
if (router.hasRoute(name)) router.removeRoute(name)
|
|
89
|
-
addedNames.delete(name)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
for (const item of items) {
|
|
94
|
-
const name = routeNameOf(item.id)
|
|
95
|
-
const childPath = item.router!.replace(/^\//, '')
|
|
96
|
-
if (addedNames.has(name) && router.hasRoute(name)) {
|
|
97
|
-
const existing = router.getRoutes().find((r) => r.name === name)
|
|
98
|
-
if (existing && existing.path.replace(/^\//, '') !== childPath) {
|
|
99
|
-
router.removeRoute(name)
|
|
100
|
-
addedNames.delete(name)
|
|
101
|
-
} else if (existing?.meta) {
|
|
102
|
-
existing.meta.title = item.name
|
|
103
|
-
existing.meta.keepAlive = item.keepAlive !== false
|
|
104
|
-
existing.meta.viewPath = item.viewPath
|
|
105
|
-
existing.meta.perms = item.perms
|
|
106
|
-
if (item.appKey) existing.meta.appKey = item.appKey
|
|
107
|
-
continue
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (!addedNames.has(name)) {
|
|
111
|
-
addedNames.add(name)
|
|
112
|
-
router.addRoute('layout', buildRoute(item))
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function clearMenuRoutesFlag() {
|
|
118
|
-
addedNames.clear()
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function removeAllMenuRoutes(router: Router) {
|
|
122
|
-
for (const name of [...addedNames]) {
|
|
123
|
-
if (router.hasRoute(name)) router.removeRoute(name)
|
|
124
|
-
}
|
|
125
|
-
addedNames.clear()
|
|
126
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { request } from '../api/client'
|
|
2
|
-
/** 系统时间由后端维护;所有方法请求体都不传 */
|
|
3
|
-
function stripTimeMeta(data: unknown): unknown {
|
|
4
|
-
if (Array.isArray(data)) return data.map((item) => stripTimeMeta(item))
|
|
5
|
-
if (data && typeof data === 'object') {
|
|
6
|
-
const out = { ...(data as Record<string, unknown>) }
|
|
7
|
-
delete out.createTime
|
|
8
|
-
delete out.updateTime
|
|
9
|
-
return out
|
|
10
|
-
}
|
|
11
|
-
return data
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** BaseService:namespace + request + 标准 CRUD */
|
|
15
|
-
export class BaseService {
|
|
16
|
-
namespace?: string
|
|
17
|
-
|
|
18
|
-
constructor(namespace?: string) {
|
|
19
|
-
if (namespace) this.namespace = namespace.replace(/^\//, '')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async request(options: ServiceRequestOptions = {}) {
|
|
23
|
-
let url = options.url || ''
|
|
24
|
-
|
|
25
|
-
if (url && !/^https?:\/\//.test(url)) {
|
|
26
|
-
if (this.namespace) {
|
|
27
|
-
const ns = this.namespace.startsWith('/')
|
|
28
|
-
? this.namespace
|
|
29
|
-
: `/${this.namespace}`
|
|
30
|
-
url = url.startsWith('/') ? `${ns}${url}` : `${ns}/${url}`
|
|
31
|
-
}
|
|
32
|
-
if (!url.startsWith('/')) url = `/${url}`
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const method = (options.method || 'GET').toUpperCase()
|
|
36
|
-
if (method === 'GET') {
|
|
37
|
-
const params = options.params || {}
|
|
38
|
-
const q = new URLSearchParams()
|
|
39
|
-
for (const [k, v] of Object.entries(params)) {
|
|
40
|
-
if (v == null) continue
|
|
41
|
-
q.set(k, String(v))
|
|
42
|
-
}
|
|
43
|
-
const qs = q.toString()
|
|
44
|
-
return request(qs ? `${url}?${qs}` : url)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return request(url, {
|
|
48
|
-
method,
|
|
49
|
-
body: JSON.stringify(stripTimeMeta(options.data ?? {})),
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
page(data: Record<string, unknown> = {}) {
|
|
54
|
-
return this.request({ url: '/page', method: 'POST', data }) as Promise<{
|
|
55
|
-
list: Record<string, unknown>[]
|
|
56
|
-
pagination: { page: number; size: number; total: number }
|
|
57
|
-
}>
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
list(data: Record<string, unknown> = {}) {
|
|
61
|
-
return this.request({
|
|
62
|
-
url: '/list',
|
|
63
|
-
method: 'POST',
|
|
64
|
-
data,
|
|
65
|
-
}) as Promise<Record<string, unknown>[]>
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
info(params: { id: number | string }) {
|
|
69
|
-
return this.request({
|
|
70
|
-
url: '/info',
|
|
71
|
-
method: 'GET',
|
|
72
|
-
params: params as Record<string, unknown>,
|
|
73
|
-
}) as Promise<Record<string, unknown>>
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
add(data: Record<string, unknown> | Record<string, unknown>[]) {
|
|
77
|
-
return this.request({ url: '/add', method: 'POST', data })
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
update(data: Record<string, unknown> | Record<string, unknown>[]) {
|
|
81
|
-
return this.request({ url: '/update', method: 'POST', data })
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
delete(
|
|
85
|
-
data:
|
|
86
|
-
| { ids: Array<number | string>; force?: boolean }
|
|
87
|
-
| Array<number | string>
|
|
88
|
-
| Array<Record<string, unknown>>,
|
|
89
|
-
) {
|
|
90
|
-
return this.request({ url: '/delete', method: 'POST', data })
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
restore(data: { ids: Array<number | string> }) {
|
|
94
|
-
return this.request({ url: '/restore', method: 'POST', data })
|
|
95
|
-
}
|
|
96
|
-
}
|
|
@@ -1,378 +0,0 @@
|
|
|
1
|
-
import { loadEps } from '../lib/eps'
|
|
2
|
-
import { BaseService } from './base'
|
|
3
|
-
|
|
4
|
-
const SIDE_ID = 'admin'
|
|
5
|
-
|
|
6
|
-
/** 标准 CRUD 之外的常用接口(EPS 未就绪时也可用) */
|
|
7
|
-
const FALLBACK_EXTRA_APIS: Record<
|
|
8
|
-
string,
|
|
9
|
-
Array<{ method: string; path: string; perms?: string[] }>
|
|
10
|
-
> = {
|
|
11
|
-
'/admin/base/department': [{ method: 'get', path: '/tree' }],
|
|
12
|
-
'/admin/base/menu': [{ method: 'get', path: '/tree' }],
|
|
13
|
-
'/admin/base/role': [
|
|
14
|
-
{ method: 'get', path: '/menus' },
|
|
15
|
-
{ method: 'post', path: '/setMenus' },
|
|
16
|
-
{ method: 'get', path: '/departments' },
|
|
17
|
-
{ method: 'post', path: '/setDepartments' },
|
|
18
|
-
],
|
|
19
|
-
'/admin/base/user': [
|
|
20
|
-
{ method: 'get', path: '/roles' },
|
|
21
|
-
{ method: 'get', path: '/roleMap' },
|
|
22
|
-
{ method: 'post', path: '/setRoles' },
|
|
23
|
-
{ method: 'post', path: '/transferSuper' },
|
|
24
|
-
{ method: 'post', path: '/moveDepartment' },
|
|
25
|
-
],
|
|
26
|
-
'/admin/base/task': [
|
|
27
|
-
{ method: 'post', path: '/start' },
|
|
28
|
-
{ method: 'post', path: '/stop' },
|
|
29
|
-
{ method: 'post', path: '/once' },
|
|
30
|
-
{ method: 'get', path: '/log' },
|
|
31
|
-
],
|
|
32
|
-
'/admin/base/log': [
|
|
33
|
-
{ method: 'post', path: '/clear' },
|
|
34
|
-
{ method: 'post', path: '/setKeep' },
|
|
35
|
-
{ method: 'post', path: '/getKeep' },
|
|
36
|
-
],
|
|
37
|
-
'/admin/base/dict/info': [
|
|
38
|
-
{ method: 'get', path: '/types' },
|
|
39
|
-
{ method: 'post', path: '/data' },
|
|
40
|
-
{ method: 'post', path: '/get' },
|
|
41
|
-
{ method: 'post', path: '/find' },
|
|
42
|
-
{ method: 'post', path: '/getValues' },
|
|
43
|
-
{ method: 'post', path: '/pathValue' },
|
|
44
|
-
{ method: 'post', path: '/childValue' },
|
|
45
|
-
],
|
|
46
|
-
'/admin/base/module': [{ method: 'post', path: '/install' }],
|
|
47
|
-
'/admin/base/comm': [{ method: 'post', path: '/upload' }],
|
|
48
|
-
'/admin/user/info': [
|
|
49
|
-
{ method: 'get', path: '/roles' },
|
|
50
|
-
{ method: 'get', path: '/roleMap' },
|
|
51
|
-
{ method: 'post', path: '/setRoles' },
|
|
52
|
-
],
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** EPS 不可用时仍保证业务页链式可调 */
|
|
56
|
-
const FALLBACK_PREFIXES = [
|
|
57
|
-
'/admin/base/menu',
|
|
58
|
-
'/admin/base/user',
|
|
59
|
-
'/admin/base/role',
|
|
60
|
-
'/admin/base/department',
|
|
61
|
-
'/admin/base/tenant',
|
|
62
|
-
'/admin/base/task',
|
|
63
|
-
'/admin/base/log',
|
|
64
|
-
'/admin/base/plugin',
|
|
65
|
-
'/admin/base/dict/info',
|
|
66
|
-
'/admin/base/dict/type',
|
|
67
|
-
'/admin/base/module',
|
|
68
|
-
'/admin/base/comm',
|
|
69
|
-
'/admin/user/info',
|
|
70
|
-
'/admin/user/role',
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
function toCamel(str: string) {
|
|
74
|
-
return str.replace(/([^-])(?:-+([^-]))/g, (_m, a, b) => a + String(b).toUpperCase())
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function methodName(path: string) {
|
|
78
|
-
return path.replace(/^\//, '').replace(/[:,\s/-]/g, '')
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function isValidName(name: string) {
|
|
82
|
-
return Boolean(name) && !['{', '}', ':'].some((c) => name.includes(c))
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** 无 EPS perms 时生成权限码 */
|
|
86
|
-
function resolvePermCode(prefix: string, action: string) {
|
|
87
|
-
const parts = prefix.replace(/^\//, '').split('/').filter(Boolean)
|
|
88
|
-
const module = parts[1] || parts[0] || 'base'
|
|
89
|
-
let resource = parts.slice(2).join(':')
|
|
90
|
-
if (resource === module) {
|
|
91
|
-
resource = module
|
|
92
|
-
} else if (resource.startsWith(`${module}:`)) {
|
|
93
|
-
resource = resource.slice(module.length + 1)
|
|
94
|
-
}
|
|
95
|
-
const head = `${module}-`
|
|
96
|
-
if (resource.startsWith(head)) resource = resource.slice(head.length)
|
|
97
|
-
resource = resource.replace(/-/g, ':')
|
|
98
|
-
if (!resource) resource = module
|
|
99
|
-
return `${module}:${resource}:${action}`
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function getMethodKeys(leaf: Record<string, unknown>) {
|
|
103
|
-
return Object.keys(leaf).filter(
|
|
104
|
-
(k) => !['namespace', 'permission', '_permission', 'request', 'search'].includes(k),
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function bindCrud(leaf: ServiceLeaf, base: BaseService) {
|
|
109
|
-
const proto = BaseService.prototype as unknown as Record<string, unknown>
|
|
110
|
-
for (const name of [
|
|
111
|
-
'request',
|
|
112
|
-
'page',
|
|
113
|
-
'list',
|
|
114
|
-
'info',
|
|
115
|
-
'add',
|
|
116
|
-
'update',
|
|
117
|
-
'delete',
|
|
118
|
-
'restore',
|
|
119
|
-
]) {
|
|
120
|
-
const fn = proto[name]
|
|
121
|
-
if (typeof fn === 'function') {
|
|
122
|
-
;(leaf as Record<string, unknown>)[name] = (
|
|
123
|
-
fn as (...a: unknown[]) => unknown
|
|
124
|
-
).bind(base)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function bindApis(leaf: ServiceLeaf, base: BaseService, apis: EpsApiItem[]) {
|
|
130
|
-
leaf.permission ||= {}
|
|
131
|
-
for (const api of apis) {
|
|
132
|
-
const name = methodName(api.path)
|
|
133
|
-
if (!isValidName(name) || /[-:]/g.test(name)) continue
|
|
134
|
-
const method = (api.method || 'get').toLowerCase()
|
|
135
|
-
// 已有同名方法则保留(避免 fallback 覆盖 EPS 绑定)
|
|
136
|
-
if (typeof (leaf as Record<string, unknown>)[name] === 'function') {
|
|
137
|
-
if (!leaf.permission[name]) {
|
|
138
|
-
leaf.permission[name] =
|
|
139
|
-
api.perms?.[0] || resolvePermCode(`/${leaf.namespace}`, name)
|
|
140
|
-
}
|
|
141
|
-
continue
|
|
142
|
-
}
|
|
143
|
-
;(leaf as Record<string, unknown>)[name] = function (
|
|
144
|
-
this: BaseService,
|
|
145
|
-
data?: unknown,
|
|
146
|
-
) {
|
|
147
|
-
return this.request({
|
|
148
|
-
url: api.path.startsWith('/') ? api.path : `/${api.path}`,
|
|
149
|
-
method,
|
|
150
|
-
[method === 'post' ? 'data' : 'params']: data,
|
|
151
|
-
})
|
|
152
|
-
}.bind(base)
|
|
153
|
-
leaf.permission[name] =
|
|
154
|
-
api.perms?.[0] || resolvePermCode(`/${leaf.namespace}`, name)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function createLeaf(namespace: string, apis: EpsApiItem[] = []): ServiceLeaf {
|
|
159
|
-
const base = new BaseService(namespace)
|
|
160
|
-
const leaf = base as unknown as ServiceLeaf
|
|
161
|
-
leaf.namespace = namespace.replace(/^\//, '')
|
|
162
|
-
leaf.permission = {}
|
|
163
|
-
leaf._permission = {}
|
|
164
|
-
|
|
165
|
-
bindCrud(leaf, base)
|
|
166
|
-
bindApis(leaf, base, apis)
|
|
167
|
-
|
|
168
|
-
for (const name of getMethodKeys(leaf as unknown as Record<string, unknown>)) {
|
|
169
|
-
if (!leaf.permission[name]) {
|
|
170
|
-
leaf.permission[name] = resolvePermCode(`/${leaf.namespace}`, name)
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return leaf
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/** 合并到已有叶子:补方法,不抹掉已有自定义 API */
|
|
178
|
-
function mergeLeaf(existing: ServiceLeaf, namespace: string, apis: EpsApiItem[]) {
|
|
179
|
-
const base = new BaseService(namespace)
|
|
180
|
-
// 确保 CRUD 在实例上(兼容旧 fallback)
|
|
181
|
-
bindCrud(existing, base)
|
|
182
|
-
bindApis(existing, base, apis)
|
|
183
|
-
existing.namespace = namespace.replace(/^\//, '')
|
|
184
|
-
existing.permission ||= {}
|
|
185
|
-
existing._permission ||= {}
|
|
186
|
-
for (const name of getMethodKeys(existing as unknown as Record<string, unknown>)) {
|
|
187
|
-
if (!existing.permission[name]) {
|
|
188
|
-
existing.permission[name] = resolvePermCode(`/${existing.namespace}`, name)
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return existing
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function attachLeaf(
|
|
195
|
-
tree: ServiceTree | Eps.Service,
|
|
196
|
-
prefix: string,
|
|
197
|
-
apis: EpsApiItem[] = [],
|
|
198
|
-
) {
|
|
199
|
-
const raw = prefix.replace(/^\//, '')
|
|
200
|
-
const arr = raw
|
|
201
|
-
.replace(new RegExp(`^${SIDE_ID}/?`), '')
|
|
202
|
-
.split('/')
|
|
203
|
-
.filter(Boolean)
|
|
204
|
-
.map(toCamel)
|
|
205
|
-
|
|
206
|
-
if (!arr.length) return undefined
|
|
207
|
-
|
|
208
|
-
let node: Record<string, unknown> = tree as unknown as Record<string, unknown>
|
|
209
|
-
for (let i = 0; i < arr.length; i++) {
|
|
210
|
-
const key = arr[i]!
|
|
211
|
-
const isLast = i === arr.length - 1
|
|
212
|
-
if (!isLast) {
|
|
213
|
-
if (!node[key] || typeof node[key] !== 'object') node[key] = {}
|
|
214
|
-
node = node[key] as Record<string, unknown>
|
|
215
|
-
continue
|
|
216
|
-
}
|
|
217
|
-
const existing = node[key] as ServiceLeaf | undefined
|
|
218
|
-
if (existing?.namespace) {
|
|
219
|
-
return mergeLeaf(existing, raw, apis)
|
|
220
|
-
}
|
|
221
|
-
const leaf = createLeaf(raw, apis)
|
|
222
|
-
node[key] = leaf
|
|
223
|
-
return leaf
|
|
224
|
-
}
|
|
225
|
-
return undefined
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function buildFromEps(map: EpsModuleMap) {
|
|
229
|
-
const list = Object.values(map).flat() as EpsEntity[]
|
|
230
|
-
for (const e of list) {
|
|
231
|
-
if (!e.prefix) continue
|
|
232
|
-
const leaf = attachLeaf(service, e.prefix, e.api || [])
|
|
233
|
-
if (leaf) {
|
|
234
|
-
const op = (e as { pageQueryOp?: Record<string, unknown> }).pageQueryOp
|
|
235
|
-
if (op) {
|
|
236
|
-
;(leaf as ServiceLeaf & { search?: unknown }).search = {
|
|
237
|
-
fieldEq: op.fieldEq,
|
|
238
|
-
fieldLike: op.fieldLike,
|
|
239
|
-
fieldArray: op.fieldArray,
|
|
240
|
-
fieldRange: op.fieldRange,
|
|
241
|
-
keyWordLikeFields: op.keyWordLikeFields,
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function buildFallback() {
|
|
249
|
-
for (const prefix of FALLBACK_PREFIXES) {
|
|
250
|
-
const extra = FALLBACK_EXTRA_APIS[prefix] || []
|
|
251
|
-
const apis = extra.map(
|
|
252
|
-
(a) =>
|
|
253
|
-
({
|
|
254
|
-
method: a.method,
|
|
255
|
-
path: a.path,
|
|
256
|
-
perms: a.perms,
|
|
257
|
-
}) as EpsApiItem,
|
|
258
|
-
)
|
|
259
|
-
attachLeaf(service, prefix, apis)
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
type ServiceRoot = Eps.Service & { request: BaseService['request'] }
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* 全局单例:npm 包经多路径解析时避免出现两份 service(一份有 tree、一份没有)。
|
|
267
|
-
*/
|
|
268
|
-
const g = globalThis as typeof globalThis & { __vome_admin_service__?: ServiceRoot }
|
|
269
|
-
|
|
270
|
-
function createServiceRoot(): ServiceRoot {
|
|
271
|
-
const root = new BaseService()
|
|
272
|
-
return {
|
|
273
|
-
request: root.request.bind(root),
|
|
274
|
-
} as ServiceRoot
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/** 全局链式 service(service.base.user.page()) */
|
|
278
|
-
export const service: ServiceRoot =
|
|
279
|
-
g.__vome_admin_service__ ?? (g.__vome_admin_service__ = createServiceRoot())
|
|
280
|
-
|
|
281
|
-
// 同步兜底(含 tree / menus 等),页面 import 时即可调用
|
|
282
|
-
buildFallback()
|
|
283
|
-
|
|
284
|
-
/** 从 EPS 构建/刷新 service 树;失败时用兜底 prefix + 自定义 API */
|
|
285
|
-
export async function createEps(force = false) {
|
|
286
|
-
try {
|
|
287
|
-
const map = (await loadEps(force)) || {}
|
|
288
|
-
if (Object.keys(map).length) buildFromEps(map)
|
|
289
|
-
} catch (e) {
|
|
290
|
-
console.warn('[vome-eps] load failed', e)
|
|
291
|
-
}
|
|
292
|
-
buildFallback()
|
|
293
|
-
return service
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (import.meta.hot) {
|
|
297
|
-
import.meta.hot.on('eps-update', () => {
|
|
298
|
-
void createEps(true).then(() => {
|
|
299
|
-
if (import.meta.env.DEV) console.log('[vome-eps] service hot updated')
|
|
300
|
-
})
|
|
301
|
-
})
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/** 登录后写入 _permission,供 CRUD / 按钮显隐 */
|
|
305
|
-
export function setServicePerms(perms: string[], isSuper = false) {
|
|
306
|
-
const list = perms || []
|
|
307
|
-
|
|
308
|
-
function deep(d: unknown) {
|
|
309
|
-
if (!d || typeof d !== 'object') return
|
|
310
|
-
const obj = d as ServiceLeaf & Record<string, unknown>
|
|
311
|
-
if (obj.permission && obj.namespace) {
|
|
312
|
-
obj._permission = {}
|
|
313
|
-
for (const key of Object.keys(obj.permission)) {
|
|
314
|
-
if (isSuper) {
|
|
315
|
-
obj._permission[key] = true
|
|
316
|
-
continue
|
|
317
|
-
}
|
|
318
|
-
const code = obj.permission[key]
|
|
319
|
-
obj._permission[key] =
|
|
320
|
-
list.includes(code) ||
|
|
321
|
-
list.some((p) =>
|
|
322
|
-
p
|
|
323
|
-
.replace(/:/g, '/')
|
|
324
|
-
.includes(`${obj.namespace.replace(/^admin\//, '')}/${key}`),
|
|
325
|
-
)
|
|
326
|
-
}
|
|
327
|
-
return
|
|
328
|
-
}
|
|
329
|
-
for (const k of Object.keys(obj)) {
|
|
330
|
-
if (k === 'request') continue
|
|
331
|
-
deep(obj[k])
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
deep(service)
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/** 解析 service.base.user 或 'base.user' */
|
|
339
|
-
export function resolveService(path: string): ServiceLeaf | undefined {
|
|
340
|
-
const parts = path.replace(/^\//, '').split('.').filter(Boolean)
|
|
341
|
-
let cur: unknown = service
|
|
342
|
-
for (const p of parts) {
|
|
343
|
-
if (!cur || typeof cur !== 'object') return undefined
|
|
344
|
-
cur = (cur as Record<string, unknown>)[p]
|
|
345
|
-
}
|
|
346
|
-
if (cur && typeof cur === 'object' && 'namespace' in (cur as object)) {
|
|
347
|
-
return cur as ServiceLeaf
|
|
348
|
-
}
|
|
349
|
-
return undefined
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/** 按 prefix 取或创建 service 叶子 */
|
|
353
|
-
export function serviceOf(prefix: string): ServiceLeaf {
|
|
354
|
-
const raw = prefix.replace(/\/$/, '')
|
|
355
|
-
const path = raw
|
|
356
|
-
.replace(/^\//, '')
|
|
357
|
-
.replace(new RegExp(`^${SIDE_ID}/?`), '')
|
|
358
|
-
.split('/')
|
|
359
|
-
.filter(Boolean)
|
|
360
|
-
.map(toCamel)
|
|
361
|
-
.join('.')
|
|
362
|
-
const hit = resolveService(path)
|
|
363
|
-
if (hit) return hit
|
|
364
|
-
const extra = FALLBACK_EXTRA_APIS[raw.startsWith('/') ? raw : `/${raw}`] || []
|
|
365
|
-
return attachLeaf(
|
|
366
|
-
service,
|
|
367
|
-
raw,
|
|
368
|
-
extra.map((a) => ({ method: a.method, path: a.path, perms: a.perms }) as EpsApiItem),
|
|
369
|
-
) as ServiceLeaf
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/** @deprecated 请用 service.base.xxx */
|
|
373
|
-
export function createEpsService(prefix: string) {
|
|
374
|
-
return serviceOf(prefix)
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
export { BaseService }
|
|
378
|
-
export type { ServiceLeaf, ServiceTree } from '../../../typings/admin/comm/service'
|
package/src/admin/stores/app.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { defineStore } from 'pinia'
|
|
2
|
-
import { nextTick } from 'vue'
|
|
3
|
-
|
|
4
|
-
const FOLD_KEY = 'vome_admin_sidebar_fold'
|
|
5
|
-
|
|
6
|
-
export const useAppStore = defineStore('app', {
|
|
7
|
-
state: () => ({
|
|
8
|
-
/** 桌面端手动折叠侧栏 */
|
|
9
|
-
sidebarFold: localStorage.getItem(FOLD_KEY) === '1',
|
|
10
|
-
/** 移动端抽屉开合 */
|
|
11
|
-
mobileOpen: false,
|
|
12
|
-
/** 为 false 时卸掉 RouterView,用于「刷新当前页」 */
|
|
13
|
-
viewAlive: true,
|
|
14
|
-
}),
|
|
15
|
-
actions: {
|
|
16
|
-
toggleSidebarFold() {
|
|
17
|
-
this.sidebarFold = !this.sidebarFold
|
|
18
|
-
localStorage.setItem(FOLD_KEY, this.sidebarFold ? '1' : '0')
|
|
19
|
-
},
|
|
20
|
-
setMobileOpen(open: boolean) {
|
|
21
|
-
this.mobileOpen = open
|
|
22
|
-
},
|
|
23
|
-
/** 重挂载当前视图(非浏览器整页刷新) */
|
|
24
|
-
async reloadView() {
|
|
25
|
-
this.viewAlive = false
|
|
26
|
-
await nextTick()
|
|
27
|
-
this.viewAlive = true
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
})
|
package/src/admin/stores/tags.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { defineStore } from 'pinia'
|
|
2
|
-
import type { RouteLocationNormalized } from 'vue-router'
|
|
3
|
-
export const useTagsStore = defineStore('tags', {
|
|
4
|
-
state: () => ({
|
|
5
|
-
list: [] as TagItem[],
|
|
6
|
-
/** KeepAlive :include,值为页面组件 name(如 base-role) */
|
|
7
|
-
caches: [] as string[],
|
|
8
|
-
}),
|
|
9
|
-
actions: {
|
|
10
|
-
add(route: RouteLocationNormalized) {
|
|
11
|
-
if (route.meta.public || route.path === '/login') return
|
|
12
|
-
const title = String(route.meta.title || route.name || route.path)
|
|
13
|
-
const componentName =
|
|
14
|
-
typeof route.meta.componentName === 'string'
|
|
15
|
-
? route.meta.componentName
|
|
16
|
-
: undefined
|
|
17
|
-
const keepAlive = route.meta.keepAlive !== false
|
|
18
|
-
|
|
19
|
-
if (componentName && keepAlive) {
|
|
20
|
-
this.addCache(componentName)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const exists = this.list.find((t) => t.path === route.path)
|
|
24
|
-
if (exists) {
|
|
25
|
-
exists.fullPath = route.fullPath
|
|
26
|
-
exists.title = title
|
|
27
|
-
exists.componentName = componentName
|
|
28
|
-
exists.keepAlive = keepAlive
|
|
29
|
-
return
|
|
30
|
-
}
|
|
31
|
-
this.list.push({
|
|
32
|
-
path: route.path,
|
|
33
|
-
fullPath: route.fullPath,
|
|
34
|
-
title,
|
|
35
|
-
name: route.name,
|
|
36
|
-
componentName,
|
|
37
|
-
keepAlive,
|
|
38
|
-
})
|
|
39
|
-
},
|
|
40
|
-
addCache(name: string) {
|
|
41
|
-
if (!name || this.caches.includes(name)) return
|
|
42
|
-
this.caches.push(name)
|
|
43
|
-
},
|
|
44
|
-
removeCache(name?: string) {
|
|
45
|
-
if (!name) return
|
|
46
|
-
this.caches = this.caches.filter((c) => c !== name)
|
|
47
|
-
},
|
|
48
|
-
remove(path: string) {
|
|
49
|
-
const i = this.list.findIndex((t) => t.path === path)
|
|
50
|
-
if (i < 0) return
|
|
51
|
-
const [tag] = this.list.splice(i, 1)
|
|
52
|
-
// 无其它 tab 引用同一组件名时才踢出缓存
|
|
53
|
-
const still =
|
|
54
|
-
tag?.componentName &&
|
|
55
|
-
this.list.some((t) => t.componentName === tag.componentName)
|
|
56
|
-
if (tag?.componentName && !still) {
|
|
57
|
-
this.removeCache(tag.componentName)
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
closeOthers(path: string) {
|
|
61
|
-
const keep = this.list.filter((t) => t.path === path || t.path === '/')
|
|
62
|
-
this.list = keep
|
|
63
|
-
this.caches = keep
|
|
64
|
-
.filter((t) => t.keepAlive && t.componentName)
|
|
65
|
-
.map((t) => t.componentName!)
|
|
66
|
-
.filter((n, i, arr) => arr.indexOf(n) === i)
|
|
67
|
-
},
|
|
68
|
-
clear() {
|
|
69
|
-
this.list = this.list.filter((t) => t.path === '/')
|
|
70
|
-
this.caches = []
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
})
|