vome-core 0.0.43 → 0.0.45
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 +71 -12
- package/dist/admin/crud/components/vm-upload-item.vue +48 -1
- 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"
|
|
@@ -69,14 +69,22 @@
|
|
|
69
69
|
<span class="vm-file-preview-viewer__tag">{{ kindLabel }}</span>
|
|
70
70
|
</div>
|
|
71
71
|
<div class="vm-file-preview-viewer__actions">
|
|
72
|
-
<
|
|
72
|
+
<button
|
|
73
|
+
v-if="useDownloadAction"
|
|
74
|
+
type="button"
|
|
73
75
|
class="vm-file-preview-viewer__link"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
@click="downloadFile"
|
|
77
|
+
>
|
|
78
|
+
下载
|
|
79
|
+
</button>
|
|
80
|
+
<button
|
|
81
|
+
v-else
|
|
82
|
+
type="button"
|
|
83
|
+
class="vm-file-preview-viewer__link"
|
|
84
|
+
@click="openInNewWindow"
|
|
77
85
|
>
|
|
78
86
|
新窗口打开
|
|
79
|
-
</
|
|
87
|
+
</button>
|
|
80
88
|
<button type="button" class="vm-file-preview-viewer__close" title="关闭" @click="closeViewer">
|
|
81
89
|
<i class="ri-close-line" />
|
|
82
90
|
</button>
|
|
@@ -161,13 +169,19 @@
|
|
|
161
169
|
<div v-else-if="kind === 'office'" class="vm-file-preview-viewer__fallback">
|
|
162
170
|
<i class="ri-file-3-line" aria-hidden="true" />
|
|
163
171
|
<p>Word / PPT 等 Office 文档暂不支持浏览器内预览。</p>
|
|
164
|
-
<p
|
|
172
|
+
<p>请点击上方「下载」后使用本地 Office / WPS 查看。</p>
|
|
173
|
+
<button type="button" class="vm-file-preview-viewer__dl-btn" @click="downloadFile">
|
|
174
|
+
下载文件
|
|
175
|
+
</button>
|
|
165
176
|
</div>
|
|
166
177
|
|
|
167
178
|
<div v-else class="vm-file-preview-viewer__fallback">
|
|
168
179
|
<i class="ri-file-3-line" aria-hidden="true" />
|
|
169
180
|
<p>该文件类型暂不支持在线预览。</p>
|
|
170
|
-
<p
|
|
181
|
+
<p>请点击下方按钮下载查看(如 .vome 插件包)。</p>
|
|
182
|
+
<button type="button" class="vm-file-preview-viewer__dl-btn" @click="downloadFile">
|
|
183
|
+
下载文件
|
|
184
|
+
</button>
|
|
171
185
|
</div>
|
|
172
186
|
</div>
|
|
173
187
|
</div>
|
|
@@ -317,6 +331,29 @@ const displayName = computed(() =>
|
|
|
317
331
|
fileDisplayName(props.fileName || src.value, '未命名文件'),
|
|
318
332
|
)
|
|
319
333
|
|
|
334
|
+
/** 无法内嵌预览的类型:只提供下载,避免「新窗口打开」崩掉(如 .vome) */
|
|
335
|
+
const useDownloadAction = computed(
|
|
336
|
+
() => kind.value === 'unsupported' || kind.value === 'office',
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
function downloadFile() {
|
|
340
|
+
const url = src.value
|
|
341
|
+
if (!url) return
|
|
342
|
+
const a = document.createElement('a')
|
|
343
|
+
a.href = url
|
|
344
|
+
a.download = displayName.value || 'download'
|
|
345
|
+
a.rel = 'noopener'
|
|
346
|
+
document.body.appendChild(a)
|
|
347
|
+
a.click()
|
|
348
|
+
a.remove()
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function openInNewWindow() {
|
|
352
|
+
const url = src.value
|
|
353
|
+
if (!url) return
|
|
354
|
+
window.open(url, '_blank', 'noopener,noreferrer')
|
|
355
|
+
}
|
|
356
|
+
|
|
320
357
|
const viewerOpen = computed({
|
|
321
358
|
get: () => (props.embedded ? !!props.open : internalOpen.value),
|
|
322
359
|
set: (v: boolean) => {
|
|
@@ -411,7 +448,10 @@ function closeViewer() {
|
|
|
411
448
|
|
|
412
449
|
function onKeydown(e: KeyboardEvent) {
|
|
413
450
|
if (!viewerOpen.value) return
|
|
414
|
-
if (e.key
|
|
451
|
+
if (e.key !== 'Escape') return
|
|
452
|
+
e.preventDefault()
|
|
453
|
+
e.stopPropagation()
|
|
454
|
+
closeViewer()
|
|
415
455
|
}
|
|
416
456
|
|
|
417
457
|
watch(viewerOpen, (open) => {
|
|
@@ -419,7 +459,8 @@ watch(viewerOpen, (open) => {
|
|
|
419
459
|
if (typeof window === 'undefined') return
|
|
420
460
|
if (open) {
|
|
421
461
|
resetView()
|
|
422
|
-
|
|
462
|
+
// 捕获阶段拦截 Escape,避免同时关掉宿主 Dialog
|
|
463
|
+
window.addEventListener('keydown', onKeydown, true)
|
|
423
464
|
if (kind.value === 'text' || kind.value === 'excel') void loadPreview()
|
|
424
465
|
if (kind.value === 'video') {
|
|
425
466
|
void nextTick(() => {
|
|
@@ -432,7 +473,7 @@ watch(viewerOpen, (open) => {
|
|
|
432
473
|
})
|
|
433
474
|
}
|
|
434
475
|
} else {
|
|
435
|
-
window.removeEventListener('keydown', onKeydown)
|
|
476
|
+
window.removeEventListener('keydown', onKeydown, true)
|
|
436
477
|
loading.value = false
|
|
437
478
|
error.value = ''
|
|
438
479
|
textContent.value = ''
|
|
@@ -445,7 +486,7 @@ watch(viewerOpen, (open) => {
|
|
|
445
486
|
onUnmounted(() => {
|
|
446
487
|
lockBody(false)
|
|
447
488
|
if (typeof window !== 'undefined') {
|
|
448
|
-
window.removeEventListener('keydown', onKeydown)
|
|
489
|
+
window.removeEventListener('keydown', onKeydown, true)
|
|
449
490
|
}
|
|
450
491
|
})
|
|
451
492
|
</script>
|
|
@@ -598,16 +639,34 @@ onUnmounted(() => {
|
|
|
598
639
|
}
|
|
599
640
|
|
|
600
641
|
.vm-file-preview-viewer__link {
|
|
642
|
+
appearance: none;
|
|
643
|
+
border: 0;
|
|
644
|
+
padding: 0;
|
|
645
|
+
background: transparent;
|
|
601
646
|
color: rgb(147 197 253);
|
|
647
|
+
font: inherit;
|
|
602
648
|
font-size: 13px;
|
|
603
649
|
font-weight: 600;
|
|
604
650
|
text-decoration: none;
|
|
651
|
+
cursor: pointer;
|
|
605
652
|
|
|
606
653
|
&:hover {
|
|
607
654
|
text-decoration: underline;
|
|
608
655
|
}
|
|
609
656
|
}
|
|
610
657
|
|
|
658
|
+
.vm-file-preview-viewer__dl-btn {
|
|
659
|
+
margin-top: 12px;
|
|
660
|
+
padding: 8px 16px;
|
|
661
|
+
border: 0;
|
|
662
|
+
border-radius: 8px;
|
|
663
|
+
background: var(--brand, #4e5dff);
|
|
664
|
+
color: #fff;
|
|
665
|
+
font-size: 14px;
|
|
666
|
+
font-weight: 600;
|
|
667
|
+
cursor: pointer;
|
|
668
|
+
}
|
|
669
|
+
|
|
611
670
|
.vm-file-preview-viewer__close {
|
|
612
671
|
display: inline-flex;
|
|
613
672
|
width: 34px;
|
|
@@ -57,15 +57,29 @@
|
|
|
57
57
|
</span>
|
|
58
58
|
|
|
59
59
|
<div v-if="previewSrc" class="vm-upload-item__actions">
|
|
60
|
-
<button
|
|
60
|
+
<button
|
|
61
|
+
v-if="canInlinePreview"
|
|
62
|
+
type="button"
|
|
63
|
+
title="预览"
|
|
64
|
+
@click.stop="previewOpen = true"
|
|
65
|
+
>
|
|
61
66
|
<i class="ri-zoom-in-line" />
|
|
62
67
|
</button>
|
|
68
|
+
<button
|
|
69
|
+
v-else
|
|
70
|
+
type="button"
|
|
71
|
+
title="下载"
|
|
72
|
+
@click.stop="downloadFile"
|
|
73
|
+
>
|
|
74
|
+
<i class="ri-download-2-line" />
|
|
75
|
+
</button>
|
|
63
76
|
<button v-if="!disabled" type="button" title="删除" @click.stop="emit('remove')">
|
|
64
77
|
<i class="ri-delete-bin-line" />
|
|
65
78
|
</button>
|
|
66
79
|
</div>
|
|
67
80
|
|
|
68
81
|
<vm-preview-viewer
|
|
82
|
+
v-if="canInlinePreview"
|
|
69
83
|
embedded
|
|
70
84
|
v-model:open="previewOpen"
|
|
71
85
|
:src="previewSrc"
|
|
@@ -77,6 +91,7 @@
|
|
|
77
91
|
<script setup lang="ts">
|
|
78
92
|
import { ref, computed, watch } from 'vue'
|
|
79
93
|
import { useVideoFrame } from '../../lib/video-frame'
|
|
94
|
+
import { getMediaPreviewKind } from '../../lib/file-preview'
|
|
80
95
|
import { extname, getUploadRule } from '../../lib/upload'
|
|
81
96
|
import VmPreviewViewer from './vm-preview-viewer.vue'
|
|
82
97
|
import type { UploadItem } from '../../../../typings/admin/comm/upload'
|
|
@@ -102,6 +117,38 @@ const imgBroken = ref(false)
|
|
|
102
117
|
|
|
103
118
|
const previewSrc = computed(() => props.item.preload || props.item.url || '')
|
|
104
119
|
|
|
120
|
+
const INLINE_KINDS = new Set([
|
|
121
|
+
'image',
|
|
122
|
+
'video',
|
|
123
|
+
'audio',
|
|
124
|
+
'pdf',
|
|
125
|
+
'excel',
|
|
126
|
+
'text',
|
|
127
|
+
])
|
|
128
|
+
|
|
129
|
+
/** 可内嵌预览才开浮层;.vome 等直接下载,避免新窗口崩溃 */
|
|
130
|
+
const canInlinePreview = computed(() => {
|
|
131
|
+
const name = props.item.name || props.item.url || ''
|
|
132
|
+
const kind = getMediaPreviewKind(name)
|
|
133
|
+
return INLINE_KINDS.has(kind)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
function downloadFile() {
|
|
137
|
+
const url = previewSrc.value
|
|
138
|
+
if (!url) return
|
|
139
|
+
const base =
|
|
140
|
+
props.item.name ||
|
|
141
|
+
String(url).split('?')[0]?.split('/').pop() ||
|
|
142
|
+
'download'
|
|
143
|
+
const a = document.createElement('a')
|
|
144
|
+
a.href = url
|
|
145
|
+
a.download = base
|
|
146
|
+
a.rel = 'noopener'
|
|
147
|
+
document.body.appendChild(a)
|
|
148
|
+
a.click()
|
|
149
|
+
a.remove()
|
|
150
|
+
}
|
|
151
|
+
|
|
105
152
|
/** 仅上传中显示;失败后隐藏,避免挡住预览/删除 */
|
|
106
153
|
const showProgress = computed(() => {
|
|
107
154
|
if (props.item.error) return false
|
|
@@ -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
|
+
}
|