vome-core 0.0.9 → 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 -413
- 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,27 +0,0 @@
|
|
|
1
|
-
import { useEventListener } from '@vueuse/core'
|
|
2
|
-
import { reactive, watch } from 'vue'
|
|
3
|
-
import { getBrowser } from '../lib/browser'
|
|
4
|
-
const browser = reactive(getBrowser()) as BrowserInfo
|
|
5
|
-
const events: Array<() => void> = []
|
|
6
|
-
|
|
7
|
-
watch(
|
|
8
|
-
() => browser.screen,
|
|
9
|
-
() => {
|
|
10
|
-
events.forEach((ev) => ev())
|
|
11
|
-
},
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
useEventListener(window, 'resize', () => {
|
|
15
|
-
Object.assign(browser, getBrowser())
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
/** 响应式浏览器信息 + 断点变化回调 */
|
|
19
|
-
export function useBrowser() {
|
|
20
|
-
return {
|
|
21
|
-
browser,
|
|
22
|
-
onScreenChange(ev: () => void, immediate = true) {
|
|
23
|
-
events.push(ev)
|
|
24
|
-
if (immediate) ev()
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { toast } from 'vue-sonner'
|
|
2
|
-
import { request } from '../api/client'
|
|
3
|
-
import { extname, filename, pathJoin, uploadUid } from '../lib/upload'
|
|
4
|
-
import type { UploadOptions, UploadResult } from '../../../typings/admin/comm/upload'
|
|
5
|
-
|
|
6
|
-
const UPLOAD_PATH = '/admin/base/comm/upload'
|
|
7
|
-
|
|
8
|
-
type SignPayload = Record<string, unknown>
|
|
9
|
-
|
|
10
|
-
const SIGN_SKIP = new Set([
|
|
11
|
-
'url',
|
|
12
|
-
'host',
|
|
13
|
-
'uploadUrl',
|
|
14
|
-
'publicDomain',
|
|
15
|
-
'previewUrl',
|
|
16
|
-
'preview',
|
|
17
|
-
])
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 云端直传:向服务端取签名 → 直传对象存储
|
|
21
|
-
* 需已安装 hook=upload 插件;配置错误由插件/接口直接抛错
|
|
22
|
-
*/
|
|
23
|
-
export function useUpload() {
|
|
24
|
-
async function toUpload(file: File, opts: UploadOptions = {}): Promise<UploadResult> {
|
|
25
|
-
const { prefixPath = 'app/base', onProgress } = opts
|
|
26
|
-
const fileId = uploadUid()
|
|
27
|
-
const ext = extname(file.name)
|
|
28
|
-
const name = `${filename(file.name)}_${fileId}${ext ? `.${ext}` : ''}`
|
|
29
|
-
const key = pathJoin(prefixPath, name)
|
|
30
|
-
|
|
31
|
-
const sign = await request<SignPayload>(UPLOAD_PATH, {
|
|
32
|
-
method: 'POST',
|
|
33
|
-
body: JSON.stringify({}),
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const host = String(sign.host || sign.url || sign.uploadUrl || '')
|
|
37
|
-
if (!host) throw new Error('上传地址无效')
|
|
38
|
-
|
|
39
|
-
const fd = new FormData()
|
|
40
|
-
fd.append('key', key)
|
|
41
|
-
for (const [k, v] of Object.entries(sign)) {
|
|
42
|
-
if (SIGN_SKIP.has(k) || v == null || fd.has(k)) continue
|
|
43
|
-
fd.append(k, String(v))
|
|
44
|
-
}
|
|
45
|
-
// OSS 要求 file 为最后一个字段
|
|
46
|
-
fd.append('file', file)
|
|
47
|
-
|
|
48
|
-
await xhrUpload(host, fd, onProgress)
|
|
49
|
-
|
|
50
|
-
const preview = String(sign.publicDomain || sign.previewUrl || host)
|
|
51
|
-
return { url: pathJoin(preview, key), key, fileId }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return { toUpload }
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function xhrUpload(
|
|
58
|
-
url: string,
|
|
59
|
-
body: FormData,
|
|
60
|
-
onProgress?: (n: number) => void,
|
|
61
|
-
): Promise<void> {
|
|
62
|
-
return new Promise((resolve, reject) => {
|
|
63
|
-
const xhr = new XMLHttpRequest()
|
|
64
|
-
xhr.open('POST', url)
|
|
65
|
-
xhr.upload.onprogress = (e) => {
|
|
66
|
-
if (!e.lengthComputable) return
|
|
67
|
-
onProgress?.(Math.min(100, Math.floor((e.loaded / e.total) * 100)))
|
|
68
|
-
}
|
|
69
|
-
xhr.onload = () => {
|
|
70
|
-
if (xhr.status < 200 || xhr.status >= 300) {
|
|
71
|
-
const msg = xhr.responseText || `上传失败 (${xhr.status})`
|
|
72
|
-
toast.error(msg.slice(0, 200))
|
|
73
|
-
reject(new Error(msg))
|
|
74
|
-
return
|
|
75
|
-
}
|
|
76
|
-
onProgress?.(100)
|
|
77
|
-
resolve()
|
|
78
|
-
}
|
|
79
|
-
xhr.onerror = () => reject(new Error('上传网络错误'))
|
|
80
|
-
xhr.send(body)
|
|
81
|
-
})
|
|
82
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { useRoute, useRouter } from 'vue-router'
|
|
2
|
-
import { service } from '../service'
|
|
3
|
-
import { useBrowser } from './useBrowser'
|
|
4
|
-
|
|
5
|
-
/** service + router + browser */
|
|
6
|
-
export function useVome() {
|
|
7
|
-
return {
|
|
8
|
-
service,
|
|
9
|
-
route: useRoute(),
|
|
10
|
-
router: useRouter(),
|
|
11
|
-
...useBrowser(),
|
|
12
|
-
}
|
|
13
|
-
}
|
package/src/admin/index.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
resolveView,
|
|
3
|
-
listViews,
|
|
4
|
-
listViewsTree,
|
|
5
|
-
viewPathToName,
|
|
6
|
-
registerViews,
|
|
7
|
-
VIEWS_RESCAN_EVENT,
|
|
8
|
-
} from './lib/module'
|
|
9
|
-
export type { ViewsTreeNode } from '../../typings/admin/vome/module'
|
|
10
|
-
export { getBrowser } from './lib/browser'
|
|
11
|
-
export type { BrowserInfo, BrowserScreen } from '../../typings/admin/vome/browser'
|
|
12
|
-
export { useBrowser } from './hooks/useBrowser'
|
|
13
|
-
/** CRUD 组件走自动引入;此处只再导出 composable / 工具,避免桶导入拖入全部 SFC */
|
|
14
|
-
export {
|
|
15
|
-
useCrud,
|
|
16
|
-
useTable,
|
|
17
|
-
useUpsert,
|
|
18
|
-
useSearch,
|
|
19
|
-
useCore,
|
|
20
|
-
CRUD_KEY,
|
|
21
|
-
} from './crud/useCrud'
|
|
22
|
-
export {
|
|
23
|
-
Plugins,
|
|
24
|
-
toTree,
|
|
25
|
-
setFocus,
|
|
26
|
-
setRules,
|
|
27
|
-
setAuto,
|
|
28
|
-
buildAutoSearchItems,
|
|
29
|
-
} from './crud/plugins'
|
|
30
|
-
export {
|
|
31
|
-
setCrudConfig,
|
|
32
|
-
getCrudConfig,
|
|
33
|
-
getCrudStyle,
|
|
34
|
-
} from './crud/style'
|
|
35
|
-
export { resolveCrudComponent, registerCrudComponent } from './crud/registry'
|
|
36
|
-
export { vmConfirm } from './crud/confirm'
|
|
37
|
-
export { deepTree, flattenTree } from './lib/tree'
|
|
38
|
-
export { config } from '#vome-host/config'
|
|
39
|
-
export { pluginDev } from './config/plugin-dev'
|
|
40
|
-
export type { PluginDevConfig, PluginScaffoldKey } from './config/plugin-dev'
|
|
41
|
-
export { router, resetMenuRoutesFlag } from './router'
|
|
42
|
-
export { useAppStore } from './stores/app'
|
|
43
|
-
export { useUserStore } from './stores/user'
|
|
44
|
-
export { useTagsStore } from './stores/tags'
|
|
45
|
-
export { loadEps, loadAllEps, getEps, findEpsEntity } from './lib/eps'
|
|
46
|
-
export type { EpsSide } from './lib/eps'
|
|
47
|
-
export { api, request, apiUrl } from './api/client'
|
|
48
|
-
export {
|
|
49
|
-
service,
|
|
50
|
-
createEps,
|
|
51
|
-
setServicePerms,
|
|
52
|
-
resolveService,
|
|
53
|
-
serviceOf,
|
|
54
|
-
createEpsService,
|
|
55
|
-
BaseService,
|
|
56
|
-
} from './service'
|
|
57
|
-
export { useVome } from './hooks/useVome'
|
|
58
|
-
export { vPerm } from './directives/perm'
|
|
59
|
-
export { cn } from './lib/cn'
|
package/src/admin/lib/browser.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export type { BrowserInfo, BrowserScreen } from '../../../typings/admin/vome/browser'
|
|
2
|
-
|
|
3
|
-
/** 根据视口计算断点与 isMini */
|
|
4
|
-
export function getBrowser(): BrowserInfo {
|
|
5
|
-
const { clientHeight: height, clientWidth: width } = document.documentElement
|
|
6
|
-
const ua = navigator.userAgent.toLowerCase()
|
|
7
|
-
|
|
8
|
-
let type = (ua.match(/firefox|chrome|safari|opera/g) || ['other'])[0]
|
|
9
|
-
if ((ua.match(/msie|trident/g) || [])[0]) type = 'msie'
|
|
10
|
-
|
|
11
|
-
let screen: BrowserScreen = 'full'
|
|
12
|
-
if (width < 768) screen = 'xs'
|
|
13
|
-
else if (width < 992) screen = 'sm'
|
|
14
|
-
else if (width < 1200) screen = 'md'
|
|
15
|
-
else if (width < 1920) screen = 'xl'
|
|
16
|
-
|
|
17
|
-
const isPC = !/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(
|
|
18
|
-
ua,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
height,
|
|
23
|
-
width,
|
|
24
|
-
type,
|
|
25
|
-
screen,
|
|
26
|
-
isMini: screen === 'xs' || !isPC,
|
|
27
|
-
}
|
|
28
|
-
}
|
package/src/admin/lib/cn.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/** Dialog 内 Teleport 浮层统一标记:点浮层时勿关闭宿主 Dialog */
|
|
2
|
-
export const DIALOG_FLOAT_CLASS = 'vm-dialog-float'
|
|
3
|
-
|
|
4
|
-
/** 判断 pointer/focus/interact-outside 是否落在 Dialog 浮层上 */
|
|
5
|
-
export function isDialogFloatTarget(event: Event): boolean {
|
|
6
|
-
const detail = (event as CustomEvent).detail as
|
|
7
|
-
| { originalEvent?: Event }
|
|
8
|
-
| undefined
|
|
9
|
-
const t = (detail?.originalEvent?.target ?? event.target) as Node | null
|
|
10
|
-
if (!t) return false
|
|
11
|
-
// 点击文字节点时 target 不是 Element,需回退到 parentElement
|
|
12
|
-
const el = t instanceof Element ? t : t.parentElement
|
|
13
|
-
return Boolean(el?.closest(`.${DIALOG_FLOAT_CLASS}`))
|
|
14
|
-
}
|
package/src/admin/lib/eps.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { request } from '../api/client'
|
|
2
|
-
|
|
3
|
-
export type EpsSide = 'admin' | 'app'
|
|
4
|
-
|
|
5
|
-
const EPS_URL: Record<EpsSide, string> = {
|
|
6
|
-
admin: '/admin/base/open/eps',
|
|
7
|
-
app: '/app/base/open/eps',
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const cache: Record<EpsSide, EpsModuleMap | null> = {
|
|
11
|
-
admin: null,
|
|
12
|
-
app: null,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** 拉取 EPS(默认 admin);公开接口失败不弹 toast */
|
|
16
|
-
export async function loadEps(force = false, side: EpsSide = 'admin') {
|
|
17
|
-
if (cache[side] && !force) return cache[side]
|
|
18
|
-
cache[side] =
|
|
19
|
-
(await request<EpsModuleMap>(EPS_URL[side], { toast: false })) || {}
|
|
20
|
-
return cache[side]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** 并行拉取 admin + app */
|
|
24
|
-
export async function loadAllEps(force = false) {
|
|
25
|
-
await Promise.all([loadEps(force, 'admin'), loadEps(force, 'app')])
|
|
26
|
-
return { admin: cache.admin, app: cache.app }
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function getEps(side: EpsSide = 'admin') {
|
|
30
|
-
return cache[side]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** 按 prefix 找实体描述,如 /admin/base/user */
|
|
34
|
-
export function findEpsEntity(prefix: string, side: EpsSide = 'admin') {
|
|
35
|
-
const map = cache[side]
|
|
36
|
-
if (!map) return undefined
|
|
37
|
-
for (const list of Object.values(map)) {
|
|
38
|
-
const hit = list.find(
|
|
39
|
-
(e) => e.prefix === prefix || e.prefix === prefix.replace(/\/$/, ''),
|
|
40
|
-
)
|
|
41
|
-
if (hit) return hit
|
|
42
|
-
}
|
|
43
|
-
return undefined
|
|
44
|
-
}
|
package/src/admin/lib/menu.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/** 侧栏可见菜单(过滤隐藏节点) */
|
|
2
|
-
export function filterShowMenus(nodes: MenuTreeNode[] | null | undefined): MenuTreeNode[] {
|
|
3
|
-
if (!Array.isArray(nodes) || !nodes.length) return []
|
|
4
|
-
return nodes
|
|
5
|
-
.filter((n) => n && n.isShow !== false)
|
|
6
|
-
.map((n) => ({
|
|
7
|
-
...n,
|
|
8
|
-
children: n.children?.length ? filterShowMenus(n.children) : undefined,
|
|
9
|
-
}))
|
|
10
|
-
.filter((n) => {
|
|
11
|
-
const t = Number(n.type)
|
|
12
|
-
return t === 0 || (t === 1 && n.router) || (n.children?.length ?? 0) > 0
|
|
13
|
-
})
|
|
14
|
-
}
|
package/src/admin/lib/module.ts
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import type { ViewLoader, ViewsTreeNode } from '../../../typings/admin/vome/module'
|
|
2
|
-
|
|
3
|
-
/** 视图重扫事件:保存 views 触发 HMR 后派发,选择器监听刷新 */
|
|
4
|
-
export const VIEWS_RESCAN_EVENT = 'vome:views-rescan'
|
|
5
|
-
|
|
6
|
-
const viewMap = new Map<string, ViewLoader>()
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
function rebuildViewMap(files: Record<string, ViewLoader>) {
|
|
10
|
-
viewMap.clear()
|
|
11
|
-
for (const [file, loader] of Object.entries(files)) {
|
|
12
|
-
if (file.includes('/components/')) continue
|
|
13
|
-
const m = file.match(/modules\/.+\.vue$/)
|
|
14
|
-
if (!m) continue
|
|
15
|
-
const rel = m[0].replace(/\.vue$/, '').replace(/\/index$/, '')
|
|
16
|
-
viewMap.set(rel, loader)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** 宿主注册业务视图 glob(包内无法扫描宿主 modules) */
|
|
21
|
-
export function registerViews(
|
|
22
|
-
files: Record<string, () => Promise<{ default: import('vue').Component }>>,
|
|
23
|
-
) {
|
|
24
|
-
rebuildViewMap(files)
|
|
25
|
-
if (typeof window !== 'undefined') {
|
|
26
|
-
window.dispatchEvent(new CustomEvent(VIEWS_RESCAN_EVENT))
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** 解析菜单 viewPath,如 modules/base/views/menu */
|
|
31
|
-
export function resolveView(viewPath: string | null | undefined): ViewLoader | undefined {
|
|
32
|
-
if (!viewPath) return undefined
|
|
33
|
-
const normalized = viewPath
|
|
34
|
-
.replace(/^\/+/, '')
|
|
35
|
-
.replace(/\.vue$/, '')
|
|
36
|
-
.replace(/\/index$/, '')
|
|
37
|
-
return (
|
|
38
|
-
viewMap.get(normalized) ||
|
|
39
|
-
viewMap.get(`modules/${normalized.replace(/^modules\//, '')}`)
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* viewPath → 页面组件 name
|
|
45
|
-
* modules/base/views/role → base-role
|
|
46
|
-
* modules/user/views/info → user-info
|
|
47
|
-
*/
|
|
48
|
-
export function viewPathToName(viewPath: string | null | undefined): string | undefined {
|
|
49
|
-
if (!viewPath) return undefined
|
|
50
|
-
const normalized = viewPath
|
|
51
|
-
.replace(/^\/+/, '')
|
|
52
|
-
.replace(/\.vue$/, '')
|
|
53
|
-
.replace(/\/index$/, '')
|
|
54
|
-
const m = normalized.match(/^(?:modules\/)?([^/]+)\/views\/(.+)$/)
|
|
55
|
-
if (m) return `${m[1]}-${m[2]!.replace(/\//g, '-')}`
|
|
56
|
-
return undefined
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function listViews() {
|
|
60
|
-
return [...viewMap.keys()].sort()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* 将扁平 viewPath 建成多列树(展示从 modules/ 后分段)
|
|
65
|
-
* modules/base/views/menu → base > views > menu
|
|
66
|
-
*/
|
|
67
|
-
export function listViewsTree(): ViewsTreeNode[] {
|
|
68
|
-
const root: ViewsTreeNode[] = []
|
|
69
|
-
|
|
70
|
-
for (const full of listViews()) {
|
|
71
|
-
const parts = full.replace(/^modules\//, '').split('/').filter(Boolean)
|
|
72
|
-
if (!parts.length) continue
|
|
73
|
-
|
|
74
|
-
let level = root
|
|
75
|
-
let acc = 'modules'
|
|
76
|
-
for (let i = 0; i < parts.length; i++) {
|
|
77
|
-
const label = parts[i]!
|
|
78
|
-
acc += `/${label}`
|
|
79
|
-
const isLeaf = i === parts.length - 1
|
|
80
|
-
let node = level.find((n) => n.label === label)
|
|
81
|
-
if (!node) {
|
|
82
|
-
node = {
|
|
83
|
-
label,
|
|
84
|
-
value: isLeaf ? full : acc,
|
|
85
|
-
isLeaf,
|
|
86
|
-
children: isLeaf ? undefined : [],
|
|
87
|
-
}
|
|
88
|
-
level.push(node)
|
|
89
|
-
} else if (isLeaf) {
|
|
90
|
-
node.isLeaf = true
|
|
91
|
-
node.value = full
|
|
92
|
-
node.children = undefined
|
|
93
|
-
}
|
|
94
|
-
if (!isLeaf) {
|
|
95
|
-
if (!node.children) node.children = []
|
|
96
|
-
level = node.children
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const sortTree = (nodes: ViewsTreeNode[]) => {
|
|
102
|
-
nodes.sort((a, b) => {
|
|
103
|
-
if (!!a.isLeaf !== !!b.isLeaf) return a.isLeaf ? 1 : -1
|
|
104
|
-
return a.label.localeCompare(b.label)
|
|
105
|
-
})
|
|
106
|
-
for (const n of nodes) {
|
|
107
|
-
if (n.children?.length) sortTree(n.children)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
sortTree(root)
|
|
111
|
-
return root
|
|
112
|
-
}
|
package/src/admin/lib/tree.ts
DELETED
package/src/admin/lib/upload.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import type { UploadFileType, UploadRule } from '../../../typings/admin/comm/upload'
|
|
2
|
-
|
|
3
|
-
/** 默认上传规则 */
|
|
4
|
-
export const DEFAULT_UPLOAD_RULES: UploadRule[] = [
|
|
5
|
-
{
|
|
6
|
-
name: '图片',
|
|
7
|
-
type: 'image',
|
|
8
|
-
color: '#67C23A',
|
|
9
|
-
exts: ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'gif', 'svg', 'webp'],
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
name: '视频',
|
|
13
|
-
type: 'video',
|
|
14
|
-
color: '#826aec',
|
|
15
|
-
exts: ['avi', 'wmv', 'mpg', 'mpeg', 'mov', 'rm', 'ram', 'swf', 'flv', 'mp4', '3gp'],
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: '音频',
|
|
19
|
-
type: 'audio',
|
|
20
|
-
color: '#826aec',
|
|
21
|
-
exts: ['mp3', 'wav', 'wma', 'mp2', 'flac', 'midi', 'ra', 'ape', 'aac', 'cda'],
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: '文档',
|
|
25
|
-
type: 'word',
|
|
26
|
-
color: '#53B7F4',
|
|
27
|
-
exts: ['doc', 'docx', 'docm', 'dot', 'dotx', 'dotm'],
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
name: '表格',
|
|
31
|
-
type: 'excel',
|
|
32
|
-
color: '#53D39C',
|
|
33
|
-
exts: ['xls', 'xlsx', 'xlsm', 'xlt', 'xltx', 'xltm'],
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
name: '演示',
|
|
37
|
-
type: 'ppt',
|
|
38
|
-
color: '#F56C6C',
|
|
39
|
-
exts: ['ppt', 'pptx', 'pptm', 'ppsx', 'ppsm', 'pps', 'potx', 'potm', 'dpt', 'dps'],
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
name: 'PDF',
|
|
43
|
-
type: 'pdf',
|
|
44
|
-
color: '#8f3500',
|
|
45
|
-
exts: ['pdf'],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: '压缩包',
|
|
49
|
-
type: 'rar',
|
|
50
|
-
color: '#FFC757',
|
|
51
|
-
exts: ['rar', 'zip', '7z', 'tar', 'gz'],
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name: '文件',
|
|
55
|
-
type: 'file',
|
|
56
|
-
color: '#909399',
|
|
57
|
-
exts: [],
|
|
58
|
-
},
|
|
59
|
-
]
|
|
60
|
-
|
|
61
|
-
export function extname(path = '') {
|
|
62
|
-
const m = String(path).split('?')[0]?.match(/\.([^.]+)$/)
|
|
63
|
-
return m ? m[1].toLowerCase() : ''
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function filename(path = '') {
|
|
67
|
-
const base = String(path).split('?')[0]?.split('/').pop() || ''
|
|
68
|
-
const ext = extname(base)
|
|
69
|
-
return ext ? base.slice(0, -(ext.length + 1)) : base
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function fileRule(path?: string, rules = DEFAULT_UPLOAD_RULES) {
|
|
73
|
-
if (path?.includes('data:image/')) {
|
|
74
|
-
return rules.find((r) => r.type === 'image')!
|
|
75
|
-
}
|
|
76
|
-
const ext = extname(path || '')
|
|
77
|
-
const hit = rules.find((r) => r.exts.includes(ext))
|
|
78
|
-
return hit || rules.find((r) => r.type === 'file')!
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function getFileType(path: string, rules = DEFAULT_UPLOAD_RULES): UploadFileType {
|
|
82
|
-
return fileRule(path, rules).type
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function getUploadRule(type: string, rules = DEFAULT_UPLOAD_RULES) {
|
|
86
|
-
return rules.find((r) => r.type === type) || rules[rules.length - 1]!
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function getUrls(list: Array<{ url?: string }>) {
|
|
90
|
-
return list.map((e) => String(e.url || '').replace(/,/g, encodeURIComponent(',')))
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function pathJoin(...parts: string[]) {
|
|
94
|
-
return parts
|
|
95
|
-
.map((p) => p.replace(/(^\/+|\/+$)/g, ''))
|
|
96
|
-
.filter(Boolean)
|
|
97
|
-
.join('/')
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function uploadUid() {
|
|
101
|
-
return `${Date.now()}_${Math.random().toString(36).slice(2, 9)}`
|
|
102
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { createRouter, createWebHistory } from 'vue-router'
|
|
2
|
-
import { api, clearTokens, getAccessToken, getRefreshToken } from '../api/client'
|
|
3
|
-
import {
|
|
4
|
-
clearMenuRoutesFlag,
|
|
5
|
-
ensureMenuRoutes,
|
|
6
|
-
removeAllMenuRoutes,
|
|
7
|
-
} from './menu-routes'
|
|
8
|
-
import Home from '#vome-host/pages/home/index.vue'
|
|
9
|
-
import Layout from '#vome-host/pages/layout/index.vue'
|
|
10
|
-
import Login from '#vome-host/pages/login/index.vue'
|
|
11
|
-
|
|
12
|
-
export const router = createRouter({
|
|
13
|
-
history: createWebHistory(),
|
|
14
|
-
routes: [
|
|
15
|
-
{
|
|
16
|
-
path: '/login',
|
|
17
|
-
name: 'login',
|
|
18
|
-
component: Login,
|
|
19
|
-
meta: { public: true },
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
path: '/',
|
|
23
|
-
name: 'layout',
|
|
24
|
-
component: Layout,
|
|
25
|
-
children: [
|
|
26
|
-
{
|
|
27
|
-
path: '',
|
|
28
|
-
name: 'home',
|
|
29
|
-
component: Home,
|
|
30
|
-
meta: { title: '首页' },
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
let menusReady = false
|
|
38
|
-
|
|
39
|
-
router.beforeEach(async (to) => {
|
|
40
|
-
if (to.meta.public) return true
|
|
41
|
-
// 无 access 时若仍有 refresh,交给 perms 请求内自动续期
|
|
42
|
-
if (!getAccessToken() && !getRefreshToken()) {
|
|
43
|
-
return { name: 'login', query: { redirect: to.fullPath } }
|
|
44
|
-
}
|
|
45
|
-
if (!menusReady) {
|
|
46
|
-
try {
|
|
47
|
-
const authz = await api.perms({ toast: false })
|
|
48
|
-
const menus = Array.isArray(authz?.menus) ? authz.menus : []
|
|
49
|
-
await ensureMenuRoutes(router, menus)
|
|
50
|
-
menusReady = true
|
|
51
|
-
if (to.matched.length <= 1 && to.path !== '/') {
|
|
52
|
-
return { ...to, replace: true }
|
|
53
|
-
}
|
|
54
|
-
} catch {
|
|
55
|
-
menusReady = false
|
|
56
|
-
clearTokens()
|
|
57
|
-
return { name: 'login', query: { redirect: to.fullPath } }
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return true
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
/** 退出/重登:卸动态路由并允许再次 ensureMenuRoutes */
|
|
64
|
-
export function resetMenuRoutesFlag() {
|
|
65
|
-
menusReady = false
|
|
66
|
-
removeAllMenuRoutes(router)
|
|
67
|
-
clearMenuRoutesFlag()
|
|
68
|
-
}
|