vome-core 0.0.44 → 0.0.46
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/config/plugin-dev.js +54 -1
- package/dist/admin/crud/components/vm-preview-viewer.vue +19 -10
- package/dist/admin/crud/components/vm-upload-item.vue +31 -14
- package/dist/admin/crud/components/vm-upload.vue +3 -0
- package/dist/admin/crud/config.js +33 -1
- package/dist/admin/crud/confirm.js +97 -1
- package/dist/admin/crud/dict.js +48 -1
- package/dist/admin/crud/index.js +74 -1
- package/dist/admin/crud/key.js +20 -1
- package/dist/admin/crud/mitt.js +21 -1
- package/dist/admin/crud/plugins.js +216 -1
- package/dist/admin/crud/span.js +35 -1
- package/dist/admin/crud/style.js +74 -1
- package/dist/admin/crud/validate.js +92 -1
- package/dist/admin/directives/perm.js +14 -1
- package/dist/admin/hooks/useUpload.js +63 -1
- package/dist/admin/lib/browser.js +24 -1
- package/dist/admin/lib/cn.js +5 -1
- package/dist/admin/lib/dialog-float.js +13 -1
- package/dist/admin/lib/export-excel.js +64 -1
- package/dist/admin/lib/file-preview.js +74 -1
- package/dist/admin/lib/import-excel.js +61 -1
- package/dist/admin/lib/json.js +42 -1
- package/dist/admin/lib/menu.js +11 -1
- package/dist/admin/lib/tree.js +1 -1
- package/dist/admin/lib/upload.js +88 -1
- package/dist/admin/lib/video-frame.js +80 -1
- package/dist/index.js +28021 -1
- package/dist/server/index.js +31407 -1
- package/dist/shared/excel.js +93 -1
- package/dist/shared/index.js +14 -1
- package/dist/shared/tree.js +39 -1
- package/package.json +1 -1
|
@@ -1 +1,54 @@
|
|
|
1
|
-
const
|
|
1
|
+
const ORG = "vomekj";
|
|
2
|
+
function giteeArchive(repo) {
|
|
3
|
+
return `https://gitee.com/${ORG}/${repo}/repository/archive/master.zip`;
|
|
4
|
+
}
|
|
5
|
+
function githubArchive(repo) {
|
|
6
|
+
return `https://github.com/${ORG}/${repo}/archive/refs/heads/master.zip`;
|
|
7
|
+
}
|
|
8
|
+
function giteeRepo(repo) {
|
|
9
|
+
return `https://gitee.com/${ORG}/${repo}`;
|
|
10
|
+
}
|
|
11
|
+
function githubRepo(repo) {
|
|
12
|
+
return `https://github.com/${ORG}/${repo}`;
|
|
13
|
+
}
|
|
14
|
+
export const pluginDev = {
|
|
15
|
+
docsUrl: "https://vomekj.com",
|
|
16
|
+
uploadUrl: "https://vomekj.com/plugins/upload",
|
|
17
|
+
mirrors: {
|
|
18
|
+
prefer: "gitee",
|
|
19
|
+
giteeOrg: `https://gitee.com/${ORG}`,
|
|
20
|
+
githubOrg: `https://github.com/${ORG}`
|
|
21
|
+
},
|
|
22
|
+
scaffolds: {
|
|
23
|
+
full: {
|
|
24
|
+
key: "full",
|
|
25
|
+
title: "前端 + 后端",
|
|
26
|
+
desc: "完整业务模块脚手架(.vome:含 server 与 web),本地开发打包后发布。",
|
|
27
|
+
repo: "vome-plugin-full",
|
|
28
|
+
repoUrl: giteeRepo("vome-plugin-full"),
|
|
29
|
+
githubRepoUrl: githubRepo("vome-plugin-full"),
|
|
30
|
+
downloadUrl: giteeArchive("vome-plugin-full"),
|
|
31
|
+
githubDownloadUrl: githubArchive("vome-plugin-full")
|
|
32
|
+
},
|
|
33
|
+
backend: {
|
|
34
|
+
key: "backend",
|
|
35
|
+
title: "纯后端",
|
|
36
|
+
desc: "钩子 / 服务端插件脚手架(.vome:仅 server),适合上传、短信、支付等能力扩展。",
|
|
37
|
+
repo: "vome-plugin-service",
|
|
38
|
+
repoUrl: giteeRepo("vome-plugin-service"),
|
|
39
|
+
githubRepoUrl: githubRepo("vome-plugin-service"),
|
|
40
|
+
downloadUrl: giteeArchive("vome-plugin-service"),
|
|
41
|
+
githubDownloadUrl: githubArchive("vome-plugin-service")
|
|
42
|
+
},
|
|
43
|
+
frontend: {
|
|
44
|
+
key: "frontend",
|
|
45
|
+
title: "纯前端",
|
|
46
|
+
desc: "后台微应用脚手架(.vome:含 web/),以 wujie 挂载独立前端页面。",
|
|
47
|
+
repo: "vome-plugin-front",
|
|
48
|
+
repoUrl: giteeRepo("vome-plugin-front"),
|
|
49
|
+
githubRepoUrl: githubRepo("vome-plugin-front"),
|
|
50
|
+
downloadUrl: giteeArchive("vome-plugin-front"),
|
|
51
|
+
githubDownloadUrl: githubArchive("vome-plugin-front")
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
<Teleport to="body">
|
|
59
59
|
<div
|
|
60
60
|
v-if="viewerOpen"
|
|
61
|
-
class="vm-file-preview-viewer"
|
|
61
|
+
class="vm-file-preview-viewer vm-dialog-float"
|
|
62
62
|
role="dialog"
|
|
63
63
|
aria-modal="true"
|
|
64
64
|
@click.self="closeViewer"
|
|
@@ -77,15 +77,14 @@
|
|
|
77
77
|
>
|
|
78
78
|
下载
|
|
79
79
|
</button>
|
|
80
|
-
<
|
|
80
|
+
<button
|
|
81
81
|
v-else
|
|
82
|
+
type="button"
|
|
82
83
|
class="vm-file-preview-viewer__link"
|
|
83
|
-
|
|
84
|
-
target="_blank"
|
|
85
|
-
rel="noopener noreferrer"
|
|
84
|
+
@click="openInNewWindow"
|
|
86
85
|
>
|
|
87
86
|
新窗口打开
|
|
88
|
-
</
|
|
87
|
+
</button>
|
|
89
88
|
<button type="button" class="vm-file-preview-viewer__close" title="关闭" @click="closeViewer">
|
|
90
89
|
<i class="ri-close-line" />
|
|
91
90
|
</button>
|
|
@@ -349,6 +348,12 @@ function downloadFile() {
|
|
|
349
348
|
a.remove()
|
|
350
349
|
}
|
|
351
350
|
|
|
351
|
+
function openInNewWindow() {
|
|
352
|
+
const url = src.value
|
|
353
|
+
if (!url) return
|
|
354
|
+
window.open(url, '_blank', 'noopener,noreferrer')
|
|
355
|
+
}
|
|
356
|
+
|
|
352
357
|
const viewerOpen = computed({
|
|
353
358
|
get: () => (props.embedded ? !!props.open : internalOpen.value),
|
|
354
359
|
set: (v: boolean) => {
|
|
@@ -443,7 +448,10 @@ function closeViewer() {
|
|
|
443
448
|
|
|
444
449
|
function onKeydown(e: KeyboardEvent) {
|
|
445
450
|
if (!viewerOpen.value) return
|
|
446
|
-
if (e.key
|
|
451
|
+
if (e.key !== 'Escape') return
|
|
452
|
+
e.preventDefault()
|
|
453
|
+
e.stopPropagation()
|
|
454
|
+
closeViewer()
|
|
447
455
|
}
|
|
448
456
|
|
|
449
457
|
watch(viewerOpen, (open) => {
|
|
@@ -451,7 +459,8 @@ watch(viewerOpen, (open) => {
|
|
|
451
459
|
if (typeof window === 'undefined') return
|
|
452
460
|
if (open) {
|
|
453
461
|
resetView()
|
|
454
|
-
|
|
462
|
+
// 捕获阶段拦截 Escape,避免同时关掉宿主 Dialog
|
|
463
|
+
window.addEventListener('keydown', onKeydown, true)
|
|
455
464
|
if (kind.value === 'text' || kind.value === 'excel') void loadPreview()
|
|
456
465
|
if (kind.value === 'video') {
|
|
457
466
|
void nextTick(() => {
|
|
@@ -464,7 +473,7 @@ watch(viewerOpen, (open) => {
|
|
|
464
473
|
})
|
|
465
474
|
}
|
|
466
475
|
} else {
|
|
467
|
-
window.removeEventListener('keydown', onKeydown)
|
|
476
|
+
window.removeEventListener('keydown', onKeydown, true)
|
|
468
477
|
loading.value = false
|
|
469
478
|
error.value = ''
|
|
470
479
|
textContent.value = ''
|
|
@@ -477,7 +486,7 @@ watch(viewerOpen, (open) => {
|
|
|
477
486
|
onUnmounted(() => {
|
|
478
487
|
lockBody(false)
|
|
479
488
|
if (typeof window !== 'undefined') {
|
|
480
|
-
window.removeEventListener('keydown', onKeydown)
|
|
489
|
+
window.removeEventListener('keydown', onKeydown, true)
|
|
481
490
|
}
|
|
482
491
|
})
|
|
483
492
|
</script>
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
v-else
|
|
70
70
|
type="button"
|
|
71
71
|
title="下载"
|
|
72
|
+
:disabled="downloading"
|
|
72
73
|
@click.stop="downloadFile"
|
|
73
74
|
>
|
|
74
75
|
<i class="ri-download-2-line" />
|
|
@@ -103,6 +104,8 @@ const props = withDefaults(
|
|
|
103
104
|
item: UploadItem
|
|
104
105
|
disabled?: boolean
|
|
105
106
|
showTag?: boolean
|
|
107
|
+
/** 私有桶等场景:先解析可访问 URL(如短时签名链)再下载 */
|
|
108
|
+
resolveDownloadUrl?: (url: string, item: UploadItem) => Promise<string | undefined>
|
|
106
109
|
}>(),
|
|
107
110
|
{
|
|
108
111
|
disabled: false,
|
|
@@ -114,6 +117,7 @@ const emit = defineEmits<{ remove: [] }>()
|
|
|
114
117
|
|
|
115
118
|
const previewOpen = ref(false)
|
|
116
119
|
const imgBroken = ref(false)
|
|
120
|
+
const downloading = ref(false)
|
|
117
121
|
|
|
118
122
|
const previewSrc = computed(() => props.item.preload || props.item.url || '')
|
|
119
123
|
|
|
@@ -133,20 +137,33 @@ const canInlinePreview = computed(() => {
|
|
|
133
137
|
return INLINE_KINDS.has(kind)
|
|
134
138
|
})
|
|
135
139
|
|
|
136
|
-
function downloadFile() {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
140
|
+
async function downloadFile() {
|
|
141
|
+
if (downloading.value) return
|
|
142
|
+
const raw = previewSrc.value
|
|
143
|
+
if (!raw) return
|
|
144
|
+
downloading.value = true
|
|
145
|
+
try {
|
|
146
|
+
let url = raw
|
|
147
|
+
if (props.resolveDownloadUrl) {
|
|
148
|
+
const signed = await props.resolveDownloadUrl(raw, props.item)
|
|
149
|
+
if (!signed) return
|
|
150
|
+
url = signed
|
|
151
|
+
}
|
|
152
|
+
const base =
|
|
153
|
+
props.item.name ||
|
|
154
|
+
String(url).split('?')[0]?.split('/').pop() ||
|
|
155
|
+
'download'
|
|
156
|
+
const a = document.createElement('a')
|
|
157
|
+
a.href = url
|
|
158
|
+
a.download = base
|
|
159
|
+
a.rel = 'noopener'
|
|
160
|
+
a.target = '_blank'
|
|
161
|
+
document.body.appendChild(a)
|
|
162
|
+
a.click()
|
|
163
|
+
a.remove()
|
|
164
|
+
} finally {
|
|
165
|
+
downloading.value = false
|
|
166
|
+
}
|
|
150
167
|
}
|
|
151
168
|
|
|
152
169
|
/** 仅上传中显示;失败后隐藏,避免挡住预览/删除 */
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
:item="item"
|
|
39
39
|
:disabled="disabled"
|
|
40
40
|
:show-tag="showTag"
|
|
41
|
+
:resolve-download-url="resolveDownloadUrl"
|
|
41
42
|
@remove="remove(index)"
|
|
42
43
|
/>
|
|
43
44
|
</div>
|
|
@@ -96,6 +97,8 @@ const props = withDefaults(
|
|
|
96
97
|
drag?: boolean
|
|
97
98
|
prefixPath?: string
|
|
98
99
|
beforeUpload?: (file: File) => boolean | Promise<boolean>
|
|
100
|
+
/** 私有桶等:下载前解析可访问 URL(短时签名链) */
|
|
101
|
+
resolveDownloadUrl?: (url: string, item: UploadItem) => Promise<string | undefined>
|
|
99
102
|
}>(),
|
|
100
103
|
{
|
|
101
104
|
modelValue: '',
|
|
@@ -1 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
import { getCrudConfig } from "./style";
|
|
2
|
+
import { CRUD_LABELS, DEFAULT_CRUD_DICT } from "./dict";
|
|
3
|
+
|
|
4
|
+
export { CRUD_LABELS, DEFAULT_CRUD_DICT };
|
|
5
|
+
export const DEFAULT_CRUD_PERMISSION = {
|
|
6
|
+
page: true,
|
|
7
|
+
list: true,
|
|
8
|
+
info: true,
|
|
9
|
+
add: true,
|
|
10
|
+
delete: true,
|
|
11
|
+
update: true
|
|
12
|
+
};
|
|
13
|
+
export function mergeDict(partial) {
|
|
14
|
+
const base = getCrudConfig().dict;
|
|
15
|
+
if (!partial)
|
|
16
|
+
return { ...base, label: { ...base.label } };
|
|
17
|
+
return {
|
|
18
|
+
...base,
|
|
19
|
+
...partial,
|
|
20
|
+
api: { ...base.api, ...partial.api },
|
|
21
|
+
pagination: { ...base.pagination, ...partial.pagination },
|
|
22
|
+
search: { ...base.search, ...partial.search },
|
|
23
|
+
sort: { ...base.sort, ...partial.sort },
|
|
24
|
+
label: { ...base.label, ...partial.label }
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function mergePermission(partial, fromService) {
|
|
28
|
+
return {
|
|
29
|
+
...DEFAULT_CRUD_PERMISSION,
|
|
30
|
+
...fromService,
|
|
31
|
+
...partial
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1 +1,97 @@
|
|
|
1
|
-
|
|
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
|
+
export function vmConfirm(options) {
|
|
10
|
+
const opts = typeof options === "string" ? { message: options } : options;
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
|
+
const open = ref(true);
|
|
13
|
+
const host = document.createElement("div");
|
|
14
|
+
document.body.appendChild(host);
|
|
15
|
+
const app = createApp({
|
|
16
|
+
setup() {
|
|
17
|
+
function finish(ok) {
|
|
18
|
+
open.value = false;
|
|
19
|
+
resolve(ok);
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
app.unmount();
|
|
22
|
+
host.remove();
|
|
23
|
+
}, 200);
|
|
24
|
+
}
|
|
25
|
+
return () => h(Dialog, {
|
|
26
|
+
open: open.value,
|
|
27
|
+
"onUpdate:open": (v) => {
|
|
28
|
+
if (!v)
|
|
29
|
+
finish(false);
|
|
30
|
+
}
|
|
31
|
+
}, {
|
|
32
|
+
default: () => h(DialogContent, { class: "vm-confirm", showCloseButton: false }, {
|
|
33
|
+
default: () => [
|
|
34
|
+
h(DialogHeader, { class: "vm-confirm__head" }, () => h(DialogTitle, { class: "vm-confirm__title" }, () => opts.title || "提示")),
|
|
35
|
+
h("div", { class: "vm-confirm__body" }, opts.message),
|
|
36
|
+
h(DialogFooter, { class: "vm-confirm__foot" }, () => [
|
|
37
|
+
h("button", {
|
|
38
|
+
type: "button",
|
|
39
|
+
class: "vm-confirm__btn is-ghost",
|
|
40
|
+
onClick: () => finish(false)
|
|
41
|
+
}, opts.cancelText || "取消"),
|
|
42
|
+
h("button", {
|
|
43
|
+
type: "button",
|
|
44
|
+
class: "vm-confirm__btn is-primary",
|
|
45
|
+
onClick: () => finish(true)
|
|
46
|
+
}, opts.confirmText || "确定")
|
|
47
|
+
])
|
|
48
|
+
]
|
|
49
|
+
})
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
app.mount(host);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (typeof document !== "undefined" && !document.getElementById("vm-confirm-style")) {
|
|
57
|
+
const style = document.createElement("style");
|
|
58
|
+
style.id = "vm-confirm-style";
|
|
59
|
+
style.textContent = `
|
|
60
|
+
.vm-confirm[data-slot='dialog-content'] {
|
|
61
|
+
width: min(400px, calc(100vw - 32px)) !important;
|
|
62
|
+
max-width: min(400px, calc(100vw - 32px)) !important;
|
|
63
|
+
gap: 0 !important;
|
|
64
|
+
padding: 0 !important;
|
|
65
|
+
border: none !important;
|
|
66
|
+
border-radius: 24px !important;
|
|
67
|
+
box-shadow: var(--shadow-soft) !important;
|
|
68
|
+
}
|
|
69
|
+
.vm-confirm__head { padding: 18px 22px 0; border-bottom: none; }
|
|
70
|
+
.vm-confirm__title { font-size: 16px; font-weight: 650; }
|
|
71
|
+
.vm-confirm__body {
|
|
72
|
+
padding: 12px 22px 8px;
|
|
73
|
+
color: var(--foreground);
|
|
74
|
+
font-size: 14px;
|
|
75
|
+
line-height: 1.6;
|
|
76
|
+
}
|
|
77
|
+
.vm-confirm__foot {
|
|
78
|
+
display: flex;
|
|
79
|
+
justify-content: flex-end;
|
|
80
|
+
gap: 8px;
|
|
81
|
+
padding: 14px 22px;
|
|
82
|
+
}
|
|
83
|
+
.vm-confirm__btn {
|
|
84
|
+
height: 36px;
|
|
85
|
+
padding: 0 16px;
|
|
86
|
+
border: none;
|
|
87
|
+
border-radius: 12px;
|
|
88
|
+
font-size: 13px;
|
|
89
|
+
font-weight: 600;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
}
|
|
92
|
+
.vm-confirm__btn.is-primary { background: var(--brand); color: #fff; }
|
|
93
|
+
.vm-confirm__btn.is-primary:hover { background: var(--brand-deep); }
|
|
94
|
+
.vm-confirm__btn.is-ghost { background: var(--muted); color: var(--foreground); }
|
|
95
|
+
`;
|
|
96
|
+
document.head.appendChild(style);
|
|
97
|
+
}
|
package/dist/admin/crud/dict.js
CHANGED
|
@@ -1 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
export const CRUD_LABELS = {
|
|
2
|
+
op: "操作",
|
|
3
|
+
add: "新增",
|
|
4
|
+
delete: "删除",
|
|
5
|
+
multiDelete: "删除",
|
|
6
|
+
export: "导出",
|
|
7
|
+
import: "导入",
|
|
8
|
+
update: "编辑",
|
|
9
|
+
refresh: "刷新",
|
|
10
|
+
info: "详情",
|
|
11
|
+
search: "搜索",
|
|
12
|
+
reset: "重置",
|
|
13
|
+
clear: "清空",
|
|
14
|
+
save: "保存",
|
|
15
|
+
close: "取消",
|
|
16
|
+
confirm: "确定",
|
|
17
|
+
advSearch: "高级搜索",
|
|
18
|
+
searchKey: "搜索关键字",
|
|
19
|
+
placeholder: "请输入",
|
|
20
|
+
tips: "提示",
|
|
21
|
+
saveSuccess: "保存成功",
|
|
22
|
+
deleteSuccess: "删除成功",
|
|
23
|
+
deleteConfirm: "此操作将数据标记为已删除,是否继续?",
|
|
24
|
+
forceDeleteConfirm: "此操作将永久删除选中数据,是否继续?",
|
|
25
|
+
empty: "暂无数据",
|
|
26
|
+
desc: "降序",
|
|
27
|
+
asc: "升序",
|
|
28
|
+
select: "选择",
|
|
29
|
+
deselect: "取消选择",
|
|
30
|
+
seeMore: "查看更多",
|
|
31
|
+
hideContent: "隐藏内容",
|
|
32
|
+
nonEmpty: "不能为空"
|
|
33
|
+
};
|
|
34
|
+
export const DEFAULT_CRUD_DICT = {
|
|
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
|
+
sort: { prop: "order", order: "sort" },
|
|
47
|
+
label: CRUD_LABELS
|
|
48
|
+
};
|
package/dist/admin/crud/index.js
CHANGED
|
@@ -1 +1,74 @@
|
|
|
1
|
-
|
|
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 VmFlex } from "./vm-flex.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 VmExportBtn } from "./vm-export-btn.vue";
|
|
14
|
+
export { default as VmImportBtn } from "./vm-import-btn.vue";
|
|
15
|
+
export { default as VmForm } from "./vm-form.vue";
|
|
16
|
+
export { default as VmAdvSearch } from "./vm-adv-search.vue";
|
|
17
|
+
export { default as VmSwitch } from "./components/vm-switch.vue";
|
|
18
|
+
export { default as VmColorPicker } from "./components/vm-color-picker.vue";
|
|
19
|
+
export { default as VmSelect } from "./components/vm-select.vue";
|
|
20
|
+
export { default as VmTreeSelect } from "./components/vm-tree-select.vue";
|
|
21
|
+
export { default as VmRadio } from "./components/vm-radio.vue";
|
|
22
|
+
export { default as VmDateText } from "./components/vm-date-text.vue";
|
|
23
|
+
export { default as VmDatePicker } from "./components/vm-date-picker.vue";
|
|
24
|
+
export { default as VmDateRange } from "./components/vm-date-range.vue";
|
|
25
|
+
export { default as VmNumberRange } from "./components/vm-number-range.vue";
|
|
26
|
+
export { default as VmMultiSelect } from "./components/vm-multi-select.vue";
|
|
27
|
+
export { default as VmDictTag } from "./components/vm-dict-tag.vue";
|
|
28
|
+
export { default as VmUserSelect } from "./components/vm-user-select.vue";
|
|
29
|
+
export { default as VmColumnCustom } from "./components/vm-column-custom.vue";
|
|
30
|
+
export { default as VmContextMenu } from "./components/vm-context-menu.vue";
|
|
31
|
+
export { default as VmUpload } from "./components/vm-upload.vue";
|
|
32
|
+
export { default as VmUploadItem } from "./components/vm-upload-item.vue";
|
|
33
|
+
export { default as VmPreviewViewer } from "./components/vm-preview-viewer.vue";
|
|
34
|
+
export { default as VmRichtext } from "./components/vm-richtext.vue";
|
|
35
|
+
export { default as VmJsonCode } from "./components/vm-json-code.vue";
|
|
36
|
+
export { default as VmJsonEditor } from "./components/vm-json-editor.vue";
|
|
37
|
+
export { default as VmStatusTag } from "./components/vm-status-tag.vue";
|
|
38
|
+
export { default as VmTagList } from "./components/vm-tag-list.vue";
|
|
39
|
+
export { default as VmAvatar } from "./components/vm-avatar.vue";
|
|
40
|
+
export { default as VmTextLink } from "./components/vm-text-link.vue";
|
|
41
|
+
export { default as VmCopyBtn } from "./components/vm-copy-btn.vue";
|
|
42
|
+
export { default as VmFormHint } from "./components/vm-form-hint.vue";
|
|
43
|
+
export { default as VmDatetimePicker } from "./components/vm-datetime-picker.vue";
|
|
44
|
+
export { default as VmEllipsisText } from "./components/vm-ellipsis-text.vue";
|
|
45
|
+
export { default as VmKvRow } from "./components/vm-kv-row.vue";
|
|
46
|
+
export { default as VmToggleSwitch } from "./components/vm-toggle-switch.vue";
|
|
47
|
+
export { vmConfirm } from "./confirm";
|
|
48
|
+
export {
|
|
49
|
+
useCrud,
|
|
50
|
+
useTable,
|
|
51
|
+
useUpsert,
|
|
52
|
+
useSearch,
|
|
53
|
+
useCore,
|
|
54
|
+
CRUD_KEY
|
|
55
|
+
} from "./useCrud";
|
|
56
|
+
export { Plugins, toTree, setFocus, setRules, setAuto, buildAutoSearchItems } from "./plugins";
|
|
57
|
+
export { deepTree, flattenTree } from "../lib/tree";
|
|
58
|
+
export { resolveCrudComponent, registerCrudComponent } from "./registry";
|
|
59
|
+
export {
|
|
60
|
+
setCrudConfig,
|
|
61
|
+
getCrudConfig,
|
|
62
|
+
getCrudStyle,
|
|
63
|
+
DEFAULT_CRUD_STYLE
|
|
64
|
+
} from "./style";
|
|
65
|
+
export {
|
|
66
|
+
FORM_COLS_DESKTOP,
|
|
67
|
+
FORM_COLS_MOBILE,
|
|
68
|
+
FORM_SPAN_FULL,
|
|
69
|
+
FORM_MQ_MOBILE,
|
|
70
|
+
getFormCols,
|
|
71
|
+
resolveFormSpan,
|
|
72
|
+
useFormCols
|
|
73
|
+
} from "./span";
|
|
74
|
+
export { mergeDict, mergePermission, DEFAULT_CRUD_DICT, CRUD_LABELS } from "./config";
|
package/dist/admin/crud/key.js
CHANGED
|
@@ -1 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
import { inject } from "vue";
|
|
2
|
+
export const CRUD_KEY = Symbol("vm-crud");
|
|
3
|
+
export const CRUD_MITT_KEY = Symbol("vm-crud-mitt");
|
|
4
|
+
export const CRUD_OPTIONS_KEY = Symbol("useCrud__options");
|
|
5
|
+
export const TABLE_OPTIONS_KEY = Symbol("useTable__options");
|
|
6
|
+
export const UPSERT_OPTIONS_KEY = Symbol("useUpsert__options");
|
|
7
|
+
export const SEARCH_OPTIONS_KEY = Symbol("useSearch__options");
|
|
8
|
+
export const TABLE_API_KEY = Symbol("vm-table-api");
|
|
9
|
+
export function injectCrudOptions() {
|
|
10
|
+
return inject(CRUD_OPTIONS_KEY, undefined);
|
|
11
|
+
}
|
|
12
|
+
export function injectTableOptions() {
|
|
13
|
+
return inject(TABLE_OPTIONS_KEY, undefined);
|
|
14
|
+
}
|
|
15
|
+
export function injectUpsertOptions() {
|
|
16
|
+
return inject(UPSERT_OPTIONS_KEY, undefined);
|
|
17
|
+
}
|
|
18
|
+
export function injectSearchOptions() {
|
|
19
|
+
return inject(SEARCH_OPTIONS_KEY, undefined);
|
|
20
|
+
}
|
package/dist/admin/crud/mitt.js
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
export class Mitt {
|
|
2
|
+
map = new Map;
|
|
3
|
+
on(type, handler) {
|
|
4
|
+
if (!this.map.has(type))
|
|
5
|
+
this.map.set(type, new Set);
|
|
6
|
+
this.map.get(type).add(handler);
|
|
7
|
+
}
|
|
8
|
+
off(type, handler) {
|
|
9
|
+
if (!handler) {
|
|
10
|
+
this.map.delete(type);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
this.map.get(type)?.delete(handler);
|
|
14
|
+
}
|
|
15
|
+
emit(type, ...args) {
|
|
16
|
+
this.map.get(type)?.forEach((fn) => fn(...args));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function createMitt() {
|
|
20
|
+
return new Mitt;
|
|
21
|
+
}
|