vome-core 0.0.9 → 0.0.12
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 +12 -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
package/src/admin/api/client.ts
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { toast } from 'vue-sonner'
|
|
2
|
-
import { config } from '#vome-host/config'
|
|
3
|
-
export type { AuthMe, AuthPerms, TokenPair } from '../../../typings/admin/base/auth'
|
|
4
|
-
export type { MenuTreeNode } from '../../../typings/admin/base/permission'
|
|
5
|
-
export type { ApiResult, RequestOptions } from '../../../typings/admin/comm/request'
|
|
6
|
-
|
|
7
|
-
/** 拼接配置中的 baseUrl(dev 为 /dev) */
|
|
8
|
-
export function apiUrl(path: string) {
|
|
9
|
-
if (/^https?:\/\//.test(path)) return path
|
|
10
|
-
const base = config.baseUrl.replace(/\/$/, '')
|
|
11
|
-
const p = path.startsWith('/') ? path : `/${path}`
|
|
12
|
-
return `${base}${p}`
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const TOKEN_KEY = 'vome_admin_access'
|
|
16
|
-
const REFRESH_KEY = 'vome_admin_refresh'
|
|
17
|
-
|
|
18
|
-
export function getAccessToken() {
|
|
19
|
-
return localStorage.getItem(TOKEN_KEY)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function setTokens(accessToken: string, refreshToken: string) {
|
|
23
|
-
localStorage.setItem(TOKEN_KEY, accessToken)
|
|
24
|
-
localStorage.setItem(REFRESH_KEY, refreshToken)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function clearTokens() {
|
|
28
|
-
localStorage.removeItem(TOKEN_KEY)
|
|
29
|
-
localStorage.removeItem(REFRESH_KEY)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function getRefreshToken() {
|
|
33
|
-
return localStorage.getItem(REFRESH_KEY)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let refreshing: Promise<boolean> | null = null
|
|
37
|
-
|
|
38
|
-
async function tryRefresh(): Promise<boolean> {
|
|
39
|
-
const refreshToken = getRefreshToken()
|
|
40
|
-
if (!refreshToken) return false
|
|
41
|
-
try {
|
|
42
|
-
const res = await fetch(apiUrl('/admin/base/auth/refresh'), {
|
|
43
|
-
method: 'POST',
|
|
44
|
-
headers: { 'content-type': 'application/json' },
|
|
45
|
-
body: JSON.stringify({ refreshToken }),
|
|
46
|
-
})
|
|
47
|
-
const json = (await res.json()) as ApiResult<TokenPair>
|
|
48
|
-
if (!res.ok || json.code !== 1000) {
|
|
49
|
-
clearTokens()
|
|
50
|
-
return false
|
|
51
|
-
}
|
|
52
|
-
setTokens(json.data.accessToken, json.data.refreshToken)
|
|
53
|
-
return true
|
|
54
|
-
} catch {
|
|
55
|
-
clearTokens()
|
|
56
|
-
return false
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** 把 Zod / 长 JSON 错误收成可读短句 */
|
|
61
|
-
export function formatApiMessage(message: string): string {
|
|
62
|
-
const t = message.trim()
|
|
63
|
-
if (t.startsWith('[')) {
|
|
64
|
-
try {
|
|
65
|
-
const arr = JSON.parse(t) as Array<{
|
|
66
|
-
path?: Array<string | number>
|
|
67
|
-
message?: string
|
|
68
|
-
}>
|
|
69
|
-
if (Array.isArray(arr) && arr.length) {
|
|
70
|
-
return arr
|
|
71
|
-
.map((i) => {
|
|
72
|
-
const path = (i.path || []).join('.')
|
|
73
|
-
const tip = i.message || '无效'
|
|
74
|
-
return path ? `${path}: ${tip}` : tip
|
|
75
|
-
})
|
|
76
|
-
.join(';')
|
|
77
|
-
}
|
|
78
|
-
} catch {
|
|
79
|
-
/* 非 JSON 数组则原样 */
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return message
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function redirectLogin() {
|
|
86
|
-
if (typeof window === 'undefined') return
|
|
87
|
-
if (location.pathname.startsWith('/login')) return
|
|
88
|
-
location.href = `/login?redirect=${encodeURIComponent(location.pathname + location.search)}`
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** 通用请求:业务码 1000 成功;鉴权失败尝试 refresh */
|
|
92
|
-
export async function request<T>(
|
|
93
|
-
path: string,
|
|
94
|
-
init?: RequestOptions,
|
|
95
|
-
): Promise<T> {
|
|
96
|
-
const { toast: showToast = true, skipRefresh, ...rest } = init || {}
|
|
97
|
-
const headers = new Headers(rest.headers)
|
|
98
|
-
if (!headers.has('content-type') && rest.body) {
|
|
99
|
-
headers.set('content-type', 'application/json')
|
|
100
|
-
}
|
|
101
|
-
const token = getAccessToken()
|
|
102
|
-
if (token) headers.set('authorization', `Bearer ${token}`)
|
|
103
|
-
|
|
104
|
-
const res = await fetch(apiUrl(path), { ...rest, headers })
|
|
105
|
-
const raw = await res.text()
|
|
106
|
-
let json: ApiResult<T> | null = null
|
|
107
|
-
try {
|
|
108
|
-
json = raw ? (JSON.parse(raw) as ApiResult<T>) : null
|
|
109
|
-
} catch {
|
|
110
|
-
// 网关/框架有时返回纯文本 Unauthorized
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (json?.code === 1000) return json.data
|
|
114
|
-
|
|
115
|
-
const rawMessage = json?.message || raw || `请求失败 (${res.status})`
|
|
116
|
-
const needAuth =
|
|
117
|
-
!skipRefresh &&
|
|
118
|
-
(res.status === 401 ||
|
|
119
|
-
/token|登录|未授权|鉴权|Unauthorized|unauthorized/i.test(rawMessage))
|
|
120
|
-
|
|
121
|
-
if (needAuth) {
|
|
122
|
-
if (getRefreshToken()) {
|
|
123
|
-
refreshing ??= tryRefresh().finally(() => {
|
|
124
|
-
refreshing = null
|
|
125
|
-
})
|
|
126
|
-
const ok = await refreshing
|
|
127
|
-
if (ok) {
|
|
128
|
-
return request<T>(path, { ...init, skipRefresh: true })
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
clearTokens()
|
|
132
|
-
redirectLogin()
|
|
133
|
-
const err = new Error('登录已失效,请重新登录') as Error & { toasted?: boolean }
|
|
134
|
-
err.toasted = true
|
|
135
|
-
throw err
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const message = formatApiMessage(rawMessage)
|
|
139
|
-
if (showToast) toast.error(message.slice(0, 200))
|
|
140
|
-
const err = new Error(message) as Error & { toasted?: boolean }
|
|
141
|
-
err.toasted = Boolean(showToast)
|
|
142
|
-
throw err
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export const api = {
|
|
146
|
-
login(body: {
|
|
147
|
-
username: string
|
|
148
|
-
password: string
|
|
149
|
-
captchaId: string
|
|
150
|
-
verifyCode: string
|
|
151
|
-
}) {
|
|
152
|
-
return request<TokenPair>('/admin/base/auth/login', {
|
|
153
|
-
method: 'POST',
|
|
154
|
-
body: JSON.stringify(body),
|
|
155
|
-
toast: true,
|
|
156
|
-
})
|
|
157
|
-
},
|
|
158
|
-
captcha(params?: { width?: number; height?: number; color?: string }) {
|
|
159
|
-
const q = new URLSearchParams()
|
|
160
|
-
if (params?.width != null) q.set('width', String(params.width))
|
|
161
|
-
if (params?.height != null) q.set('height', String(params.height))
|
|
162
|
-
if (params?.color) q.set('color', params.color)
|
|
163
|
-
const qs = q.toString()
|
|
164
|
-
return request<{ captchaId: string; data: string }>(
|
|
165
|
-
`/admin/base/open/captcha${qs ? `?${qs}` : ''}`,
|
|
166
|
-
{ toast: false },
|
|
167
|
-
)
|
|
168
|
-
},
|
|
169
|
-
me(init?: RequestOptions) {
|
|
170
|
-
return request<AuthMe>('/admin/base/auth/me', init)
|
|
171
|
-
},
|
|
172
|
-
perms(init?: RequestOptions) {
|
|
173
|
-
return request<AuthPerms>('/admin/base/auth/perms', init)
|
|
174
|
-
},
|
|
175
|
-
logout() {
|
|
176
|
-
const refreshToken = getRefreshToken()
|
|
177
|
-
return request<null>('/admin/base/auth/logout', {
|
|
178
|
-
method: 'POST',
|
|
179
|
-
body: JSON.stringify({ refreshToken: refreshToken || '' }),
|
|
180
|
-
toast: false,
|
|
181
|
-
}).catch(() => null)
|
|
182
|
-
},
|
|
183
|
-
}
|
|
184
|
-
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 插件开发入口(官网文档 / 上传 / 脚手架)
|
|
3
|
-
* 域名变更随 @vome-core 发版,宿主勿覆盖。
|
|
4
|
-
*/
|
|
5
|
-
export const pluginDev = {
|
|
6
|
-
docsUrl: 'https://vome.dev/docs/plugin',
|
|
7
|
-
uploadUrl: 'https://vome.dev/plugins/upload',
|
|
8
|
-
scaffolds: {
|
|
9
|
-
full: {
|
|
10
|
-
key: 'full',
|
|
11
|
-
title: '前端 + 后端',
|
|
12
|
-
desc: '完整业务模块脚手架(.vome: 含 server 与 web), 本地开发打包后发布到官网。',
|
|
13
|
-
downloadUrl: 'https://vome.dev/scaffolds/plugin-full.zip',
|
|
14
|
-
},
|
|
15
|
-
backend: {
|
|
16
|
-
key: 'backend',
|
|
17
|
-
title: '纯后端',
|
|
18
|
-
desc: '钩子 / 服务端插件脚手架(.vome: 仅 server), 适合上传、短信、支付等能力扩展。',
|
|
19
|
-
downloadUrl: 'https://vome.dev/scaffolds/plugin-backend.zip',
|
|
20
|
-
},
|
|
21
|
-
frontend: {
|
|
22
|
-
key: 'frontend',
|
|
23
|
-
title: '纯前端',
|
|
24
|
-
desc: '后台微应用脚手架(.vapp), 以 wujie 挂载独立前端页面。',
|
|
25
|
-
downloadUrl: 'https://vome.dev/scaffolds/plugin-frontend.zip',
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
} as const
|
|
29
|
-
|
|
30
|
-
export type PluginDevConfig = typeof pluginDev
|
|
31
|
-
export type PluginScaffoldKey = keyof typeof pluginDev.scaffolds
|
package/src/admin/crud/config.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { getCrudConfig } from './style'
|
|
2
|
-
import { CRUD_LABELS, DEFAULT_CRUD_DICT } from './dict'
|
|
3
|
-
|
|
4
|
-
export { CRUD_LABELS, DEFAULT_CRUD_DICT }
|
|
5
|
-
|
|
6
|
-
export const DEFAULT_CRUD_PERMISSION: CrudPermission = {
|
|
7
|
-
page: true,
|
|
8
|
-
list: true,
|
|
9
|
-
info: true,
|
|
10
|
-
add: true,
|
|
11
|
-
delete: true,
|
|
12
|
-
update: true,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function mergeDict(partial?: Partial<CrudDict>): CrudDict {
|
|
16
|
-
const base = getCrudConfig().dict
|
|
17
|
-
if (!partial) return { ...base, label: { ...base.label } }
|
|
18
|
-
return {
|
|
19
|
-
...base,
|
|
20
|
-
...partial,
|
|
21
|
-
api: { ...base.api, ...partial.api },
|
|
22
|
-
pagination: { ...base.pagination, ...partial.pagination },
|
|
23
|
-
search: { ...base.search, ...partial.search },
|
|
24
|
-
sort: { ...base.sort, ...partial.sort },
|
|
25
|
-
label: { ...base.label, ...partial.label },
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function mergePermission(
|
|
30
|
-
partial?: Partial<CrudPermission>,
|
|
31
|
-
fromService?: Partial<CrudPermission>,
|
|
32
|
-
): CrudPermission {
|
|
33
|
-
return {
|
|
34
|
-
...DEFAULT_CRUD_PERMISSION,
|
|
35
|
-
...fromService,
|
|
36
|
-
...partial,
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { createApp, h, ref } from 'vue'
|
|
2
|
-
import {
|
|
3
|
-
Dialog,
|
|
4
|
-
DialogContent,
|
|
5
|
-
DialogFooter,
|
|
6
|
-
DialogHeader,
|
|
7
|
-
DialogTitle,
|
|
8
|
-
} from '#vome-host/components/ui/dialog'
|
|
9
|
-
|
|
10
|
-
type ConfirmOptions = {
|
|
11
|
-
title?: string
|
|
12
|
-
message: string
|
|
13
|
-
confirmText?: string
|
|
14
|
-
cancelText?: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 确认对话框
|
|
19
|
-
*/
|
|
20
|
-
export function vmConfirm(options: ConfirmOptions | string): Promise<boolean> {
|
|
21
|
-
const opts: ConfirmOptions =
|
|
22
|
-
typeof options === 'string' ? { message: options } : options
|
|
23
|
-
|
|
24
|
-
return new Promise((resolve) => {
|
|
25
|
-
const open = ref(true)
|
|
26
|
-
const host = document.createElement('div')
|
|
27
|
-
document.body.appendChild(host)
|
|
28
|
-
|
|
29
|
-
const app = createApp({
|
|
30
|
-
setup() {
|
|
31
|
-
function finish(ok: boolean) {
|
|
32
|
-
open.value = false
|
|
33
|
-
resolve(ok)
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
app.unmount()
|
|
36
|
-
host.remove()
|
|
37
|
-
}, 200)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return () =>
|
|
41
|
-
h(
|
|
42
|
-
Dialog,
|
|
43
|
-
{
|
|
44
|
-
open: open.value,
|
|
45
|
-
'onUpdate:open': (v: boolean) => {
|
|
46
|
-
if (!v) finish(false)
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
default: () =>
|
|
51
|
-
h(
|
|
52
|
-
DialogContent,
|
|
53
|
-
{ class: 'vm-confirm', showCloseButton: false },
|
|
54
|
-
{
|
|
55
|
-
default: () => [
|
|
56
|
-
h(DialogHeader, { class: 'vm-confirm__head' }, () =>
|
|
57
|
-
h(DialogTitle, { class: 'vm-confirm__title' }, () =>
|
|
58
|
-
opts.title || '提示',
|
|
59
|
-
),
|
|
60
|
-
),
|
|
61
|
-
h('div', { class: 'vm-confirm__body' }, opts.message),
|
|
62
|
-
h(DialogFooter, { class: 'vm-confirm__foot' }, () => [
|
|
63
|
-
h(
|
|
64
|
-
'button',
|
|
65
|
-
{
|
|
66
|
-
type: 'button',
|
|
67
|
-
class: 'vm-confirm__btn is-ghost',
|
|
68
|
-
onClick: () => finish(false),
|
|
69
|
-
},
|
|
70
|
-
opts.cancelText || '取消',
|
|
71
|
-
),
|
|
72
|
-
h(
|
|
73
|
-
'button',
|
|
74
|
-
{
|
|
75
|
-
type: 'button',
|
|
76
|
-
class: 'vm-confirm__btn is-primary',
|
|
77
|
-
onClick: () => finish(true),
|
|
78
|
-
},
|
|
79
|
-
opts.confirmText || '确定',
|
|
80
|
-
),
|
|
81
|
-
]),
|
|
82
|
-
],
|
|
83
|
-
},
|
|
84
|
-
),
|
|
85
|
-
},
|
|
86
|
-
)
|
|
87
|
-
},
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
app.mount(host)
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (typeof document !== 'undefined' && !document.getElementById('vm-confirm-style')) {
|
|
95
|
-
const style = document.createElement('style')
|
|
96
|
-
style.id = 'vm-confirm-style'
|
|
97
|
-
style.textContent = `
|
|
98
|
-
.vm-confirm[data-slot='dialog-content'] {
|
|
99
|
-
width: min(400px, calc(100vw - 32px)) !important;
|
|
100
|
-
max-width: min(400px, calc(100vw - 32px)) !important;
|
|
101
|
-
gap: 0 !important;
|
|
102
|
-
padding: 0 !important;
|
|
103
|
-
border: none !important;
|
|
104
|
-
border-radius: 24px !important;
|
|
105
|
-
box-shadow: var(--shadow-soft) !important;
|
|
106
|
-
}
|
|
107
|
-
.vm-confirm__head { padding: 18px 22px 0; border-bottom: none; }
|
|
108
|
-
.vm-confirm__title { font-size: 16px; font-weight: 650; }
|
|
109
|
-
.vm-confirm__body {
|
|
110
|
-
padding: 12px 22px 8px;
|
|
111
|
-
color: var(--foreground);
|
|
112
|
-
font-size: 14px;
|
|
113
|
-
line-height: 1.6;
|
|
114
|
-
}
|
|
115
|
-
.vm-confirm__foot {
|
|
116
|
-
display: flex;
|
|
117
|
-
justify-content: flex-end;
|
|
118
|
-
gap: 8px;
|
|
119
|
-
padding: 14px 22px;
|
|
120
|
-
}
|
|
121
|
-
.vm-confirm__btn {
|
|
122
|
-
height: 36px;
|
|
123
|
-
padding: 0 16px;
|
|
124
|
-
border: none;
|
|
125
|
-
border-radius: 12px;
|
|
126
|
-
font-size: 13px;
|
|
127
|
-
font-weight: 600;
|
|
128
|
-
cursor: pointer;
|
|
129
|
-
}
|
|
130
|
-
.vm-confirm__btn.is-primary { background: var(--brand); color: #fff; }
|
|
131
|
-
.vm-confirm__btn.is-primary:hover { background: var(--brand-deep); }
|
|
132
|
-
.vm-confirm__btn.is-ghost { background: var(--muted); color: var(--foreground); }
|
|
133
|
-
`
|
|
134
|
-
document.head.appendChild(style)
|
|
135
|
-
}
|
package/src/admin/crud/dict.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/** 表格/表单默认文案(zh-cn) */
|
|
2
|
-
export const CRUD_LABELS: CrudDict['label'] = {
|
|
3
|
-
op: '操作',
|
|
4
|
-
add: '新增',
|
|
5
|
-
delete: '删除',
|
|
6
|
-
multiDelete: '删除',
|
|
7
|
-
update: '编辑',
|
|
8
|
-
refresh: '刷新',
|
|
9
|
-
info: '详情',
|
|
10
|
-
search: '搜索',
|
|
11
|
-
reset: '重置',
|
|
12
|
-
clear: '清空',
|
|
13
|
-
save: '保存',
|
|
14
|
-
close: '取消',
|
|
15
|
-
confirm: '确定',
|
|
16
|
-
advSearch: '高级搜索',
|
|
17
|
-
searchKey: '搜索关键字',
|
|
18
|
-
placeholder: '请输入',
|
|
19
|
-
tips: '提示',
|
|
20
|
-
saveSuccess: '保存成功',
|
|
21
|
-
deleteSuccess: '删除成功',
|
|
22
|
-
deleteConfirm: '此操作将数据标记为已删除,是否继续?',
|
|
23
|
-
forceDeleteConfirm: '此操作将永久删除选中数据,是否继续?',
|
|
24
|
-
empty: '暂无数据',
|
|
25
|
-
desc: '降序',
|
|
26
|
-
asc: '升序',
|
|
27
|
-
select: '选择',
|
|
28
|
-
deselect: '取消选择',
|
|
29
|
-
seeMore: '查看更多',
|
|
30
|
-
hideContent: '隐藏内容',
|
|
31
|
-
nonEmpty: '不能为空',
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const DEFAULT_CRUD_DICT: CrudDict = {
|
|
35
|
-
primaryId: 'id',
|
|
36
|
-
api: {
|
|
37
|
-
list: 'list',
|
|
38
|
-
add: 'add',
|
|
39
|
-
update: 'update',
|
|
40
|
-
delete: 'delete',
|
|
41
|
-
info: 'info',
|
|
42
|
-
page: 'page',
|
|
43
|
-
},
|
|
44
|
-
pagination: { page: 'page', size: 'size' },
|
|
45
|
-
search: { keyWord: 'keyWord', query: 'query' },
|
|
46
|
-
// QueryOp:order=字段名,sort=asc|desc(键名为 order/sort)
|
|
47
|
-
sort: { prop: 'order', order: 'sort' },
|
|
48
|
-
label: CRUD_LABELS,
|
|
49
|
-
}
|
package/src/admin/crud/index.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
export { default as VmCrud } from './vm-crud.vue'
|
|
2
|
-
export { default as VmSearch } from './vm-search.vue'
|
|
3
|
-
export { default as VmSearchKey } from './vm-search-key.vue'
|
|
4
|
-
export { default as VmTable } from './vm-table.vue'
|
|
5
|
-
export { default as VmPagination } from './vm-pagination.vue'
|
|
6
|
-
export { default as VmUpsert } from './vm-upsert.vue'
|
|
7
|
-
export { default as VmToolbar } from './vm-toolbar.vue'
|
|
8
|
-
export { default as VmRow } from './vm-row.vue'
|
|
9
|
-
export { default as VmFlex1 } from './vm-flex1.vue'
|
|
10
|
-
export { default as VmAddBtn } from './vm-add-btn.vue'
|
|
11
|
-
export { default as VmRefreshBtn } from './vm-refresh-btn.vue'
|
|
12
|
-
export { default as VmMultiDeleteBtn } from './vm-multi-delete-btn.vue'
|
|
13
|
-
export { default as VmDialog } from './vm-dialog.vue'
|
|
14
|
-
export { default as VmForm } from './vm-form.vue'
|
|
15
|
-
export { default as VmAdvSearch } from './vm-adv-search.vue'
|
|
16
|
-
|
|
17
|
-
export { default as VmSwitch } from './components/vm-switch.vue'
|
|
18
|
-
export { default as VmSelect } from './components/vm-select.vue'
|
|
19
|
-
export { default as VmTreeSelect } from './components/vm-tree-select.vue'
|
|
20
|
-
export { default as VmRadio } from './components/vm-radio.vue'
|
|
21
|
-
export { default as VmDateText } from './components/vm-date-text.vue'
|
|
22
|
-
export { default as VmDatePicker } from './components/vm-date-picker.vue'
|
|
23
|
-
export { default as VmDateRange } from './components/vm-date-range.vue'
|
|
24
|
-
export { default as VmNumberRange } from './components/vm-number-range.vue'
|
|
25
|
-
export { default as VmMultiSelect } from './components/vm-multi-select.vue'
|
|
26
|
-
export { default as VmDictTag } from './components/vm-dict-tag.vue'
|
|
27
|
-
export { default as VmUserSelect } from './components/vm-user-select.vue'
|
|
28
|
-
export { default as VmColumnCustom } from './components/vm-column-custom.vue'
|
|
29
|
-
export { default as VmContextMenu } from './components/vm-context-menu.vue'
|
|
30
|
-
export { default as VmUpload } from './components/vm-upload.vue'
|
|
31
|
-
export { default as VmUploadItem } from './components/vm-upload-item.vue'
|
|
32
|
-
export { default as VmFileIcon } from './components/vm-file-icon.vue'
|
|
33
|
-
|
|
34
|
-
export { vmConfirm } from './confirm'
|
|
35
|
-
export {
|
|
36
|
-
useCrud,
|
|
37
|
-
useTable,
|
|
38
|
-
useUpsert,
|
|
39
|
-
useSearch,
|
|
40
|
-
useCore,
|
|
41
|
-
CRUD_KEY,
|
|
42
|
-
} from './useCrud'
|
|
43
|
-
|
|
44
|
-
export { Plugins, toTree, setFocus, setRules, setAuto, buildAutoSearchItems } from './plugins'
|
|
45
|
-
export { deepTree, flattenTree } from '../lib/tree'
|
|
46
|
-
export { resolveCrudComponent, registerCrudComponent } from './registry'
|
|
47
|
-
export {
|
|
48
|
-
setCrudConfig,
|
|
49
|
-
getCrudConfig,
|
|
50
|
-
getCrudStyle,
|
|
51
|
-
DEFAULT_CRUD_STYLE,
|
|
52
|
-
} from './style'
|
|
53
|
-
|
|
54
|
-
export {
|
|
55
|
-
FORM_COLS_DESKTOP,
|
|
56
|
-
FORM_COLS_MOBILE,
|
|
57
|
-
FORM_SPAN_FULL,
|
|
58
|
-
FORM_MQ_MOBILE,
|
|
59
|
-
getFormCols,
|
|
60
|
-
resolveFormSpan,
|
|
61
|
-
useFormCols,
|
|
62
|
-
} from './span'
|
|
63
|
-
|
|
64
|
-
export { mergeDict, mergePermission, DEFAULT_CRUD_DICT, CRUD_LABELS } from './config'
|
|
65
|
-
|
|
66
|
-
export type {
|
|
67
|
-
CrudService,
|
|
68
|
-
CrudColumn,
|
|
69
|
-
CrudSearchItem,
|
|
70
|
-
CrudFormItem,
|
|
71
|
-
CrudContext,
|
|
72
|
-
CrudTrashMode,
|
|
73
|
-
CrudOptions,
|
|
74
|
-
CrudTableOptions,
|
|
75
|
-
CrudUpsertOptions,
|
|
76
|
-
CrudSearchOptions,
|
|
77
|
-
CrudPermission,
|
|
78
|
-
CrudDict,
|
|
79
|
-
} from '../../../typings/admin/comm/crud'
|
package/src/admin/crud/key.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { inject, type InjectionKey } from 'vue'
|
|
2
|
-
import type {
|
|
3
|
-
CrudColumn,
|
|
4
|
-
CrudContext,
|
|
5
|
-
CrudOptions,
|
|
6
|
-
CrudSearchOptions,
|
|
7
|
-
CrudTableOptions,
|
|
8
|
-
CrudUpsertOptions,
|
|
9
|
-
} from '../../../typings/admin/comm/crud'
|
|
10
|
-
import type { Mitt } from './mitt'
|
|
11
|
-
|
|
12
|
-
export const CRUD_KEY: InjectionKey<CrudContext> = Symbol('vm-crud')
|
|
13
|
-
export const CRUD_MITT_KEY: InjectionKey<Mitt> = Symbol('vm-crud-mitt')
|
|
14
|
-
export const CRUD_OPTIONS_KEY: InjectionKey<CrudOptions> = Symbol('useCrud__options')
|
|
15
|
-
export const TABLE_OPTIONS_KEY: InjectionKey<CrudTableOptions> =
|
|
16
|
-
Symbol('useTable__options')
|
|
17
|
-
export const UPSERT_OPTIONS_KEY: InjectionKey<CrudUpsertOptions> =
|
|
18
|
-
Symbol('useUpsert__options')
|
|
19
|
-
export const SEARCH_OPTIONS_KEY: InjectionKey<CrudSearchOptions> =
|
|
20
|
-
Symbol('useSearch__options')
|
|
21
|
-
|
|
22
|
-
/** Table 实例 API(ColumnCustom / showColumn 等) */
|
|
23
|
-
export type TableApi = {
|
|
24
|
-
setColumns: (cols: CrudColumn[]) => void
|
|
25
|
-
showColumn: (prop: string) => void
|
|
26
|
-
hideColumn: (prop: string) => void
|
|
27
|
-
getColumns: () => CrudColumn[]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const TABLE_API_KEY: InjectionKey<TableApi> = Symbol('vm-table-api')
|
|
31
|
-
|
|
32
|
-
/** inject(KEY, undefined) 在严格模式下会推断为 never,统一走 helper */
|
|
33
|
-
export function injectCrudOptions(): CrudOptions | undefined {
|
|
34
|
-
return inject(CRUD_OPTIONS_KEY, undefined as CrudOptions | undefined)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function injectTableOptions(): CrudTableOptions | undefined {
|
|
38
|
-
return inject(TABLE_OPTIONS_KEY, undefined as CrudTableOptions | undefined)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function injectUpsertOptions(): CrudUpsertOptions | undefined {
|
|
42
|
-
return inject(UPSERT_OPTIONS_KEY, undefined as CrudUpsertOptions | undefined)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function injectSearchOptions(): CrudSearchOptions | undefined {
|
|
46
|
-
return inject(SEARCH_OPTIONS_KEY, undefined as CrudSearchOptions | undefined)
|
|
47
|
-
}
|
package/src/admin/crud/mitt.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
type Handler = (...args: unknown[]) => void
|
|
2
|
-
|
|
3
|
-
/** 轻量 mitt,crud 事件总线 */
|
|
4
|
-
export class Mitt {
|
|
5
|
-
private map = new Map<string, Set<Handler>>()
|
|
6
|
-
|
|
7
|
-
on(type: string, handler: Handler) {
|
|
8
|
-
if (!this.map.has(type)) this.map.set(type, new Set())
|
|
9
|
-
this.map.get(type)!.add(handler)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
off(type: string, handler?: Handler) {
|
|
13
|
-
if (!handler) {
|
|
14
|
-
this.map.delete(type)
|
|
15
|
-
return
|
|
16
|
-
}
|
|
17
|
-
this.map.get(type)?.delete(handler)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
emit(type: string, ...args: unknown[]) {
|
|
21
|
-
this.map.get(type)?.forEach((fn) => fn(...args))
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function createMitt() {
|
|
26
|
-
return new Mitt()
|
|
27
|
-
}
|