tree-upload-vue3 1.0.0
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/README.md +42 -0
- package/dist/App.vue.d.ts +2 -0
- package/dist/components/SchemaPreview.vue.d.ts +12 -0
- package/dist/components/SchemaTable.vue.d.ts +13 -0
- package/dist/components/SchemaTemplate.vue.d.ts +9 -0
- package/dist/components/SchemaTree.vue.d.ts +14 -0
- package/dist/components/SchemaUpload.vue.d.ts +13 -0
- package/dist/components/TreeUpload.vue.d.ts +11 -0
- package/dist/index.d.ts +5 -0
- package/dist/main.d.ts +0 -0
- package/dist/tree-upload-vue3.css +1 -0
- package/dist/tree-upload-vue3.es.js +748 -0
- package/dist/tree-upload-vue3.umd.js +1 -0
- package/dist/types/index.d.ts +158 -0
- package/dist/utils/schema-helper.d.ts +3 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Tree Upload Component (Vue 3 + Element Plus)
|
|
2
|
+
|
|
3
|
+
一个基于 Schema 驱动的低代码树形文件管理组件。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- **声明式配置**: 通过 JSON Schema 定义树、上传、表格、预览和权限。
|
|
8
|
+
- **左侧树**: 支持静态/API数据源,支持节点增删改(Context Menu)。
|
|
9
|
+
- **右侧上传**: 支持多文件、拖拽、自动上传,支持自定义 Headers 和额外参数。
|
|
10
|
+
- **右侧表格**: 支持静态/API数据源,分页,自定义列,格式化器。
|
|
11
|
+
- **文件预览**: 集成 `file-preview-vue3-ts`,支持多种文件格式。
|
|
12
|
+
- **模板下载**: 支持节点级模板配置。
|
|
13
|
+
- **权限控制**: 细粒度的权限规则引擎。
|
|
14
|
+
- **上下文**: 支持 `$currentNode.id` 等动态变量替换。
|
|
15
|
+
|
|
16
|
+
## 目录结构
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
src/
|
|
20
|
+
├── components/
|
|
21
|
+
│ ├── TreeUpload.vue # 主组件(入口)
|
|
22
|
+
│ ├── SchemaTree.vue # 左侧树
|
|
23
|
+
│ ├── SchemaUpload.vue # 上传区
|
|
24
|
+
│ ├── SchemaTable.vue # 文件列表
|
|
25
|
+
│ ├── SchemaTemplate.vue # 模板下载
|
|
26
|
+
│ └── SchemaPreview.vue # 预览弹窗
|
|
27
|
+
├── types/
|
|
28
|
+
│ └── index.ts # Schema 类型定义
|
|
29
|
+
├── utils/
|
|
30
|
+
│ └── schema-helper.ts # 权限校验与变量替换工具
|
|
31
|
+
├── App.vue # 示例应用
|
|
32
|
+
└── main.ts # 入口文件
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 快速开始
|
|
36
|
+
|
|
37
|
+
1. 安装依赖: `npm install`
|
|
38
|
+
2. 启动开发服务器: `npm run dev`
|
|
39
|
+
|
|
40
|
+
## Schema 示例
|
|
41
|
+
|
|
42
|
+
请参考 `src/App.vue` 中的完整示例配置。
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PreviewSchema, FileItem } from '../types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
schema: PreviewSchema;
|
|
4
|
+
modelValue: boolean;
|
|
5
|
+
file: FileItem | null;
|
|
6
|
+
};
|
|
7
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
8
|
+
"update:modelValue": (...args: any[]) => void;
|
|
9
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
10
|
+
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
11
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TableSchema, FileItem } from '../types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
schema: TableSchema;
|
|
4
|
+
files?: FileItem[];
|
|
5
|
+
};
|
|
6
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
7
|
+
action: (...args: any[]) => void;
|
|
8
|
+
refresh: (...args: any[]) => void;
|
|
9
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
10
|
+
onAction?: ((...args: any[]) => any) | undefined;
|
|
11
|
+
onRefresh?: ((...args: any[]) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface TemplateItem {
|
|
2
|
+
name: string;
|
|
3
|
+
url: string;
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
templates: TemplateItem[];
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TreeSchema } from '../types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
schema: TreeSchema;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
6
|
+
"node-click": (...args: any[]) => void;
|
|
7
|
+
action: (...args: any[]) => void;
|
|
8
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
9
|
+
"onNode-click"?: ((...args: any[]) => any) | undefined;
|
|
10
|
+
onAction?: ((...args: any[]) => any) | undefined;
|
|
11
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
12
|
+
treeRef: unknown;
|
|
13
|
+
}, HTMLDivElement>;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UploadSchema } from '../types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
schema: UploadSchema;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
7
|
+
"upload-success": (...args: any[]) => void;
|
|
8
|
+
"upload-error": (...args: any[]) => void;
|
|
9
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
10
|
+
"onUpload-success"?: ((...args: any[]) => any) | undefined;
|
|
11
|
+
"onUpload-error"?: ((...args: any[]) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TreeUploadSchema } from '../types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
schema: TreeUploadSchema;
|
|
4
|
+
mode?: 'view' | 'edit';
|
|
5
|
+
};
|
|
6
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
7
|
+
mode: "view" | "edit";
|
|
8
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
9
|
+
nodeFormRef: unknown;
|
|
10
|
+
}, HTMLDivElement>;
|
|
11
|
+
export default _default;
|
package/dist/index.d.ts
ADDED
package/dist/main.d.ts
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.schema-tree[data-v-493d816e]{height:100%;position:relative;display:flex;flex-direction:column}.tree-toolbar[data-v-493d816e]{padding:8px;border-bottom:1px solid #f0f2f5;display:flex;gap:8px}.custom-tree-node[data-v-493d816e]{flex:1;display:flex;align-items:center;justify-content:space-between;font-size:14px;padding-right:8px}.custom-tree-node .actions[data-v-493d816e]{display:none}.custom-tree-node:hover .actions[data-v-493d816e]{display:inline-flex}.context-menu[data-v-493d816e]{position:fixed;z-index:1000;background:#fff;border:1px solid #dcdfe6;box-shadow:0 2px 12px #0000001a;border-radius:4px;padding:5px 0;min-width:120px}.context-menu-item[data-v-493d816e]{padding:8px 16px;cursor:pointer;display:flex;align-items:center;gap:8px;font-size:13px;color:#606266}.context-menu-item[data-v-493d816e]:hover{background-color:#f5f7fa;color:#409eff}.schema-upload[data-v-b2da1f5f]{width:100%}.schema-table[data-v-d92346a5]{height:100%;display:flex;flex-direction:column}.table-toolbar[data-v-d92346a5]{margin-bottom:12px}.pagination-wrapper[data-v-d92346a5]{margin-top:12px;display:flex;justify-content:flex-end}.schema-template[data-v-5468ee4e]{margin-bottom:12px;background-color:#f4f4f5;padding:8px 12px;border-radius:4px;border:1px solid #e9e9eb}.template-container[data-v-5468ee4e]{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.label[data-v-5468ee4e]{font-size:13px;color:#909399;white-space:nowrap}.tags-wrapper[data-v-5468ee4e]{display:flex;flex-wrap:wrap;gap:8px}.template-tag[data-v-5468ee4e]{cursor:pointer;border:none;background-color:#fff;transition:all .2s}.template-tag[data-v-5468ee4e]:hover{color:#409eff;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.tag-content[data-v-5468ee4e]{display:flex;align-items:center;gap:4px}.tpl-name[data-v-5468ee4e]{line-height:1}.preview-content[data-v-caf5bb4b]{height:100%;min-height:500px;display:flex;flex-direction:column}.custom-header[data-v-caf5bb4b]{display:flex;justify-content:space-between;align-items:center;padding-right:0}.header-controls[data-v-caf5bb4b]{display:flex;align-items:center;gap:8px}.tree-upload-container[data-v-346b7c9b]{display:flex;height:100%;border:1px solid #dcdfe6;background:#fff}.tree-pane[data-v-346b7c9b]{border-right:1px solid #dcdfe6;height:100%;overflow-y:auto;padding:10px;box-sizing:border-box}.content-pane[data-v-346b7c9b]{flex:1;display:flex;flex-direction:column;padding:16px;overflow:hidden}.top-section[data-v-346b7c9b]{margin-bottom:16px}.table-section[data-v-346b7c9b]{flex:1;overflow:hidden}
|
|
@@ -0,0 +1,748 @@
|
|
|
1
|
+
import { defineComponent as j, ref as C, computed as D, onMounted as ae, onUnmounted as le, resolveComponent as h, createElementBlock as S, openBlock as a, createCommentVNode as w, createVNode as y, Fragment as E, renderList as K, createBlock as p, withCtx as d, createTextVNode as R, resolveDynamicComponent as O, toDisplayString as F, createElementVNode as $, withModifiers as ne, normalizeStyle as Q, inject as Z, createSlots as oe, watch as ee, resolveDirective as ie, withDirectives as se, unref as X, normalizeClass as ce, reactive as G, provide as re, nextTick as ue } from "vue";
|
|
2
|
+
import { ElMessage as H } from "element-plus";
|
|
3
|
+
import { Download as de, Close as me } from "@element-plus/icons-vue";
|
|
4
|
+
import J from "file-preview-vue3-ts";
|
|
5
|
+
const fe = { class: "schema-tree" }, pe = {
|
|
6
|
+
key: 0,
|
|
7
|
+
class: "tree-toolbar"
|
|
8
|
+
}, he = { class: "custom-tree-node" }, ve = {
|
|
9
|
+
key: 0,
|
|
10
|
+
class: "actions"
|
|
11
|
+
}, be = ["onClick"], ge = /* @__PURE__ */ j({
|
|
12
|
+
__name: "SchemaTree",
|
|
13
|
+
props: {
|
|
14
|
+
schema: {}
|
|
15
|
+
},
|
|
16
|
+
emits: ["node-click", "action"],
|
|
17
|
+
setup(e, { emit: r }) {
|
|
18
|
+
const t = e, v = r, b = C(), s = C(!1), k = C({ x: 0, y: 0 }), g = C(null), V = D(() => t.schema.dataSource.type === "static" ? t.schema.dataSource.data : []), N = {
|
|
19
|
+
label: t.schema.labelKey || "label",
|
|
20
|
+
children: t.schema.childrenKey || "children"
|
|
21
|
+
}, U = D(() => t.schema.actions?.filter((n) => n.position === "toolbar") || []), T = D(() => t.schema.actions?.filter((n) => n.position === "node") || []), A = D(() => t.schema.actions?.filter((n) => n.position === "contextMenu") || []), l = (n) => {
|
|
22
|
+
s.value = !1, v("node-click", n);
|
|
23
|
+
}, _ = (n, x) => {
|
|
24
|
+
A.value.length !== 0 && (n.preventDefault(), s.value = !0, k.value = { x: n.clientX, y: n.clientY }, g.value = x);
|
|
25
|
+
}, z = (n, x) => {
|
|
26
|
+
s.value = !1, !(n.confirm && !confirm(n.confirm.message || "Are you sure?")) && v("action", n.key, x);
|
|
27
|
+
}, c = () => {
|
|
28
|
+
s.value = !1;
|
|
29
|
+
};
|
|
30
|
+
return ae(() => {
|
|
31
|
+
document.addEventListener("click", c);
|
|
32
|
+
}), le(() => {
|
|
33
|
+
document.removeEventListener("click", c);
|
|
34
|
+
}), (n, x) => {
|
|
35
|
+
const B = h("el-icon"), L = h("el-button"), u = h("el-tooltip"), i = h("el-tree");
|
|
36
|
+
return a(), S("div", fe, [
|
|
37
|
+
U.value.length ? (a(), S("div", pe, [
|
|
38
|
+
(a(!0), S(E, null, K(U.value, (m) => (a(), p(L, {
|
|
39
|
+
key: m.key,
|
|
40
|
+
type: "primary",
|
|
41
|
+
link: "",
|
|
42
|
+
onClick: (o) => z(m, null)
|
|
43
|
+
}, {
|
|
44
|
+
default: d(() => [
|
|
45
|
+
m.icon ? (a(), p(B, { key: 0 }, {
|
|
46
|
+
default: d(() => [
|
|
47
|
+
(a(), p(O(m.icon)))
|
|
48
|
+
]),
|
|
49
|
+
_: 2
|
|
50
|
+
}, 1024)) : w("", !0),
|
|
51
|
+
R(" " + F(m.label), 1)
|
|
52
|
+
]),
|
|
53
|
+
_: 2
|
|
54
|
+
}, 1032, ["onClick"]))), 128))
|
|
55
|
+
])) : w("", !0),
|
|
56
|
+
y(i, {
|
|
57
|
+
ref_key: "treeRef",
|
|
58
|
+
ref: b,
|
|
59
|
+
data: V.value,
|
|
60
|
+
"node-key": e.schema.nodeKey || "id",
|
|
61
|
+
props: N,
|
|
62
|
+
"default-expand-all": e.schema.ui?.defaultExpandAll,
|
|
63
|
+
"highlight-current": e.schema.ui?.highlightCurrent,
|
|
64
|
+
"expand-on-click-node": !1,
|
|
65
|
+
onNodeClick: l,
|
|
66
|
+
onNodeContextmenu: _
|
|
67
|
+
}, {
|
|
68
|
+
default: d(({ node: m, data: o }) => [
|
|
69
|
+
$("span", he, [
|
|
70
|
+
$("span", null, F(m.label), 1),
|
|
71
|
+
T.value.length ? (a(), S("span", ve, [
|
|
72
|
+
(a(!0), S(E, null, K(T.value, (f) => (a(), p(u, {
|
|
73
|
+
key: f.key,
|
|
74
|
+
content: f.label,
|
|
75
|
+
placement: "top",
|
|
76
|
+
"show-after": 200
|
|
77
|
+
}, {
|
|
78
|
+
default: d(() => [
|
|
79
|
+
y(L, {
|
|
80
|
+
link: "",
|
|
81
|
+
type: "primary",
|
|
82
|
+
onClick: ne((M) => z(f, o), ["stop"])
|
|
83
|
+
}, {
|
|
84
|
+
default: d(() => [
|
|
85
|
+
f.icon ? (a(), p(B, { key: 0 }, {
|
|
86
|
+
default: d(() => [
|
|
87
|
+
(a(), p(O(f.icon)))
|
|
88
|
+
]),
|
|
89
|
+
_: 2
|
|
90
|
+
}, 1024)) : w("", !0)
|
|
91
|
+
]),
|
|
92
|
+
_: 2
|
|
93
|
+
}, 1032, ["onClick"])
|
|
94
|
+
]),
|
|
95
|
+
_: 2
|
|
96
|
+
}, 1032, ["content"]))), 128))
|
|
97
|
+
])) : w("", !0)
|
|
98
|
+
])
|
|
99
|
+
]),
|
|
100
|
+
_: 1
|
|
101
|
+
}, 8, ["data", "node-key", "default-expand-all", "highlight-current"]),
|
|
102
|
+
s.value ? (a(), S("div", {
|
|
103
|
+
key: 1,
|
|
104
|
+
class: "context-menu",
|
|
105
|
+
style: Q({ left: k.value.x + "px", top: k.value.y + "px" })
|
|
106
|
+
}, [
|
|
107
|
+
(a(!0), S(E, null, K(A.value, (m) => (a(), S("div", {
|
|
108
|
+
key: m.key,
|
|
109
|
+
class: "context-menu-item",
|
|
110
|
+
onClick: (o) => z(m, g.value)
|
|
111
|
+
}, [
|
|
112
|
+
m.icon ? (a(), p(B, { key: 0 }, {
|
|
113
|
+
default: d(() => [
|
|
114
|
+
(a(), p(O(m.icon)))
|
|
115
|
+
]),
|
|
116
|
+
_: 2
|
|
117
|
+
}, 1024)) : w("", !0),
|
|
118
|
+
R(" " + F(m.label), 1)
|
|
119
|
+
], 8, be))), 128))
|
|
120
|
+
], 4)) : w("", !0)
|
|
121
|
+
]);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}), q = (e, r) => {
|
|
125
|
+
const t = e.__vccOpts || e;
|
|
126
|
+
for (const [v, b] of r)
|
|
127
|
+
t[v] = b;
|
|
128
|
+
return t;
|
|
129
|
+
}, _e = /* @__PURE__ */ q(ge, [["__scopeId", "data-v-493d816e"]]);
|
|
130
|
+
function Y(e, r, t) {
|
|
131
|
+
return r.permissions ? r.permissions.default?.[e] !== !1 : !0;
|
|
132
|
+
}
|
|
133
|
+
function te(e, r) {
|
|
134
|
+
if (!e) return e;
|
|
135
|
+
let t = e;
|
|
136
|
+
const v = r.variables || {};
|
|
137
|
+
return v.currentNode && (t = t.replace(/\$currentNode\.id/g, String(v.currentNode.id)), t = t.replace(/\$currentNode\.label/g, v.currentNode.label)), t;
|
|
138
|
+
}
|
|
139
|
+
const ye = {
|
|
140
|
+
key: 0,
|
|
141
|
+
class: "schema-upload"
|
|
142
|
+
}, ke = { class: "el-upload__text" }, xe = { class: "el-upload__tip" }, Se = /* @__PURE__ */ j({
|
|
143
|
+
__name: "SchemaUpload",
|
|
144
|
+
props: {
|
|
145
|
+
schema: {},
|
|
146
|
+
disabled: { type: Boolean }
|
|
147
|
+
},
|
|
148
|
+
emits: ["upload-success", "upload-error"],
|
|
149
|
+
setup(e, { emit: r }) {
|
|
150
|
+
const t = e, v = r, b = Z("schemaContext", {}), s = D(() => {
|
|
151
|
+
const l = b.variables?.currentNode?.meta?.upload || {};
|
|
152
|
+
return {
|
|
153
|
+
...t.schema,
|
|
154
|
+
...l,
|
|
155
|
+
// Override with node-level config
|
|
156
|
+
// Explicitly handle fields that might be in meta
|
|
157
|
+
limit: l.limit ?? t.schema.limit,
|
|
158
|
+
maxSize: l.maxSize,
|
|
159
|
+
// Custom field: bytes
|
|
160
|
+
minLimit: l.minLimit,
|
|
161
|
+
// Custom field
|
|
162
|
+
accept: l.accept ?? t.schema.accept,
|
|
163
|
+
multiple: l.multiple ?? t.schema.multiple,
|
|
164
|
+
drag: l.drag ?? t.schema.drag,
|
|
165
|
+
autoUpload: l.autoUpload ?? t.schema.autoUpload
|
|
166
|
+
};
|
|
167
|
+
}), k = D(() => t.schema.headers || {}), g = D(() => {
|
|
168
|
+
const l = t.schema.data || {}, _ = {};
|
|
169
|
+
for (const z in l) {
|
|
170
|
+
const c = l[z];
|
|
171
|
+
typeof c == "string" ? _[z] = te(c, b) : _[z] = c;
|
|
172
|
+
}
|
|
173
|
+
return _;
|
|
174
|
+
}), V = D(() => {
|
|
175
|
+
let l = t.schema.ui?.tipText || "";
|
|
176
|
+
const _ = [];
|
|
177
|
+
if (s.value.maxSize) {
|
|
178
|
+
const z = (s.value.maxSize / 1024 / 1024).toFixed(1);
|
|
179
|
+
_.push(`大小限制 ${z}MB`);
|
|
180
|
+
}
|
|
181
|
+
return s.value.limit && _.push(`数量限制 ${s.value.limit}个`), s.value.accept && _.push(`格式 ${s.value.accept}`), _.length ? `${l} (${_.join(", ")})` : l;
|
|
182
|
+
}), N = (l) => {
|
|
183
|
+
const _ = s.value.maxSize;
|
|
184
|
+
return _ && l.size > _ ? (H.error(`文件大小不能超过 ${(_ / 1024 / 1024).toFixed(1)}MB!`), !1) : !0;
|
|
185
|
+
}, U = () => {
|
|
186
|
+
H.warning(`当前限制选择 ${s.value.limit} 个文件`);
|
|
187
|
+
}, T = (l) => {
|
|
188
|
+
v("upload-success", l);
|
|
189
|
+
}, A = (l) => {
|
|
190
|
+
v("upload-error", l);
|
|
191
|
+
};
|
|
192
|
+
return (l, _) => {
|
|
193
|
+
const z = h("upload-filled"), c = h("el-icon"), n = h("el-button"), x = h("el-upload");
|
|
194
|
+
return e.schema.enabled ? (a(), S("div", ye, [
|
|
195
|
+
y(x, {
|
|
196
|
+
class: "upload-demo",
|
|
197
|
+
action: e.schema.action,
|
|
198
|
+
method: e.schema.method || "post",
|
|
199
|
+
headers: k.value,
|
|
200
|
+
data: g.value,
|
|
201
|
+
multiple: s.value.multiple,
|
|
202
|
+
drag: s.value.drag,
|
|
203
|
+
accept: s.value.accept,
|
|
204
|
+
limit: s.value.limit,
|
|
205
|
+
"auto-upload": s.value.autoUpload !== !1,
|
|
206
|
+
disabled: e.disabled,
|
|
207
|
+
"show-file-list": e.schema.ui?.showFileList,
|
|
208
|
+
"before-upload": N,
|
|
209
|
+
"on-exceed": U,
|
|
210
|
+
onSuccess: T,
|
|
211
|
+
onError: A
|
|
212
|
+
}, oe({
|
|
213
|
+
default: d(() => [
|
|
214
|
+
s.value.drag ? (a(), S(E, { key: 0 }, [
|
|
215
|
+
y(c, { class: "el-icon--upload" }, {
|
|
216
|
+
default: d(() => [
|
|
217
|
+
y(z)
|
|
218
|
+
]),
|
|
219
|
+
_: 1
|
|
220
|
+
}),
|
|
221
|
+
$("div", ke, F(e.schema.ui?.buttonText || "Drop file here or click to upload"), 1)
|
|
222
|
+
], 64)) : w("", !0)
|
|
223
|
+
]),
|
|
224
|
+
_: 2
|
|
225
|
+
}, [
|
|
226
|
+
s.value.drag ? void 0 : {
|
|
227
|
+
name: "trigger",
|
|
228
|
+
fn: d(() => [
|
|
229
|
+
y(n, { type: "primary" }, {
|
|
230
|
+
default: d(() => [
|
|
231
|
+
R(F(e.schema.ui?.buttonText || "Click to upload"), 1)
|
|
232
|
+
]),
|
|
233
|
+
_: 1
|
|
234
|
+
})
|
|
235
|
+
]),
|
|
236
|
+
key: "0"
|
|
237
|
+
},
|
|
238
|
+
e.schema.ui?.showTip ? {
|
|
239
|
+
name: "tip",
|
|
240
|
+
fn: d(() => [
|
|
241
|
+
$("div", xe, F(V.value), 1)
|
|
242
|
+
]),
|
|
243
|
+
key: "1"
|
|
244
|
+
} : void 0
|
|
245
|
+
]), 1032, ["action", "method", "headers", "data", "multiple", "drag", "accept", "limit", "auto-upload", "disabled", "show-file-list"])
|
|
246
|
+
])) : w("", !0);
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}), we = /* @__PURE__ */ q(Se, [["__scopeId", "data-v-b2da1f5f"]]), Ce = { class: "schema-table" }, $e = {
|
|
250
|
+
key: 0,
|
|
251
|
+
class: "table-toolbar"
|
|
252
|
+
}, Ve = {
|
|
253
|
+
key: 1,
|
|
254
|
+
class: "pagination-wrapper"
|
|
255
|
+
}, ze = /* @__PURE__ */ j({
|
|
256
|
+
__name: "SchemaTable",
|
|
257
|
+
props: {
|
|
258
|
+
schema: {},
|
|
259
|
+
files: {}
|
|
260
|
+
},
|
|
261
|
+
emits: ["action", "refresh"],
|
|
262
|
+
setup(e, { emit: r }) {
|
|
263
|
+
const t = e, v = r, b = Z("schemaContext", {}), s = C(!1), k = C(1), g = C(t.schema.ui?.pagination?.pageSize || 20), V = C(0), N = C([]), U = D(() => t.files ? t.files : t.schema.dataSource.type === "static" ? t.schema.dataSource.data : N.value), T = (c, n) => {
|
|
264
|
+
if (!n) return c;
|
|
265
|
+
if (n === "fileSize") {
|
|
266
|
+
const x = Number(c);
|
|
267
|
+
return isNaN(x) ? c : x < 1024 ? x + " B" : x < 1024 * 1024 ? (x / 1024).toFixed(2) + " KB" : (x / 1024 / 1024).toFixed(2) + " MB";
|
|
268
|
+
}
|
|
269
|
+
return c;
|
|
270
|
+
}, A = (c, n) => {
|
|
271
|
+
c.confirm && !confirm(c.confirm.message || "Are you sure?") || v("action", c.key, n);
|
|
272
|
+
}, l = async () => {
|
|
273
|
+
if (t.schema.dataSource.type === "api") {
|
|
274
|
+
s.value = !0;
|
|
275
|
+
try {
|
|
276
|
+
const c = t.schema.dataSource, n = { ...c.params };
|
|
277
|
+
t.schema.ui?.pagination?.enabled && (n.page = k.value, n.pageSize = g.value);
|
|
278
|
+
for (const x in n)
|
|
279
|
+
typeof n[x] == "string" && (n[x] = te(n[x], b));
|
|
280
|
+
console.log("Fetching Table Data:", c.url, n), c.url;
|
|
281
|
+
} catch (c) {
|
|
282
|
+
console.error(c);
|
|
283
|
+
} finally {
|
|
284
|
+
s.value = !1;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}, _ = (c) => {
|
|
288
|
+
g.value = c, l();
|
|
289
|
+
}, z = (c) => {
|
|
290
|
+
k.value = c, l();
|
|
291
|
+
};
|
|
292
|
+
return ee(() => b.variables?.currentNode, (c) => {
|
|
293
|
+
c && t.schema.dataSource.type === "api" && l();
|
|
294
|
+
}, { deep: !0 }), (c, n) => {
|
|
295
|
+
const x = h("el-icon"), B = h("el-button"), L = h("el-table-column"), u = h("el-table"), i = h("el-pagination"), m = ie("loading");
|
|
296
|
+
return a(), S("div", Ce, [
|
|
297
|
+
e.schema.toolbarActions?.length ? (a(), S("div", $e, [
|
|
298
|
+
(a(!0), S(E, null, K(e.schema.toolbarActions, (o) => (a(), p(B, {
|
|
299
|
+
key: o.key,
|
|
300
|
+
type: o.type || "default",
|
|
301
|
+
onClick: (f) => A(o, null)
|
|
302
|
+
}, {
|
|
303
|
+
default: d(() => [
|
|
304
|
+
o.icon ? (a(), p(x, { key: 0 }, {
|
|
305
|
+
default: d(() => [
|
|
306
|
+
(a(), p(O(o.icon)))
|
|
307
|
+
]),
|
|
308
|
+
_: 2
|
|
309
|
+
}, 1024)) : w("", !0),
|
|
310
|
+
R(" " + F(o.label), 1)
|
|
311
|
+
]),
|
|
312
|
+
_: 2
|
|
313
|
+
}, 1032, ["type", "onClick"]))), 128))
|
|
314
|
+
])) : w("", !0),
|
|
315
|
+
se((a(), p(u, {
|
|
316
|
+
data: U.value,
|
|
317
|
+
stripe: e.schema.ui?.stripe,
|
|
318
|
+
border: e.schema.ui?.border,
|
|
319
|
+
size: e.schema.ui?.size,
|
|
320
|
+
style: { width: "100%", height: "100%", flex: "1" }
|
|
321
|
+
}, {
|
|
322
|
+
default: d(() => [
|
|
323
|
+
(a(!0), S(E, null, K(e.schema.columns, (o) => (a(), p(L, {
|
|
324
|
+
key: o.prop,
|
|
325
|
+
prop: o.prop,
|
|
326
|
+
label: o.label,
|
|
327
|
+
width: o.width,
|
|
328
|
+
align: o.align,
|
|
329
|
+
fixed: o.fixed,
|
|
330
|
+
sortable: o.sortable
|
|
331
|
+
}, {
|
|
332
|
+
default: d((f) => [
|
|
333
|
+
R(F(T(f.row[o.prop], o.formatter)), 1)
|
|
334
|
+
]),
|
|
335
|
+
_: 2
|
|
336
|
+
}, 1032, ["prop", "label", "width", "align", "fixed", "sortable"]))), 128)),
|
|
337
|
+
e.schema.actions?.length ? (a(), p(L, {
|
|
338
|
+
key: 0,
|
|
339
|
+
label: "操作",
|
|
340
|
+
fixed: "right",
|
|
341
|
+
width: "200"
|
|
342
|
+
}, {
|
|
343
|
+
default: d((o) => [
|
|
344
|
+
(a(!0), S(E, null, K(e.schema.actions, (f) => (a(), p(B, {
|
|
345
|
+
key: f.key,
|
|
346
|
+
type: f.type || "primary",
|
|
347
|
+
link: "",
|
|
348
|
+
onClick: (M) => A(f, o.row)
|
|
349
|
+
}, {
|
|
350
|
+
default: d(() => [
|
|
351
|
+
R(F(f.label), 1)
|
|
352
|
+
]),
|
|
353
|
+
_: 2
|
|
354
|
+
}, 1032, ["type", "onClick"]))), 128))
|
|
355
|
+
]),
|
|
356
|
+
_: 1
|
|
357
|
+
})) : w("", !0)
|
|
358
|
+
]),
|
|
359
|
+
_: 1
|
|
360
|
+
}, 8, ["data", "stripe", "border", "size"])), [
|
|
361
|
+
[m, s.value]
|
|
362
|
+
]),
|
|
363
|
+
e.schema.ui?.pagination?.enabled ? (a(), S("div", Ve, [
|
|
364
|
+
y(i, {
|
|
365
|
+
"current-page": k.value,
|
|
366
|
+
"onUpdate:currentPage": n[0] || (n[0] = (o) => k.value = o),
|
|
367
|
+
"page-size": g.value,
|
|
368
|
+
"onUpdate:pageSize": n[1] || (n[1] = (o) => g.value = o),
|
|
369
|
+
"page-sizes": [10, 20, 50, 100],
|
|
370
|
+
layout: e.schema.ui?.pagination?.layout || "total, sizes, prev, pager, next, jumper",
|
|
371
|
+
total: V.value,
|
|
372
|
+
onSizeChange: _,
|
|
373
|
+
onCurrentChange: z
|
|
374
|
+
}, null, 8, ["current-page", "page-size", "layout", "total"])
|
|
375
|
+
])) : w("", !0)
|
|
376
|
+
]);
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
}), Te = /* @__PURE__ */ q(ze, [["__scopeId", "data-v-d92346a5"]]), De = { class: "schema-template" }, Ne = { class: "template-container" }, Ue = { class: "tags-wrapper" }, Ae = { class: "tag-content" }, Fe = { class: "tpl-name" }, Me = /* @__PURE__ */ j({
|
|
380
|
+
__name: "SchemaTemplate",
|
|
381
|
+
props: {
|
|
382
|
+
templates: {}
|
|
383
|
+
},
|
|
384
|
+
setup(e) {
|
|
385
|
+
const r = (t) => {
|
|
386
|
+
window.open(t.url, "_blank");
|
|
387
|
+
};
|
|
388
|
+
return (t, v) => {
|
|
389
|
+
const b = h("el-icon"), s = h("el-tag");
|
|
390
|
+
return a(), S("div", De, [
|
|
391
|
+
$("div", Ne, [
|
|
392
|
+
v[0] || (v[0] = $("span", { class: "label" }, "可用模板:", -1)),
|
|
393
|
+
$("div", Ue, [
|
|
394
|
+
(a(!0), S(E, null, K(e.templates, (k, g) => (a(), p(s, {
|
|
395
|
+
key: g,
|
|
396
|
+
class: "template-tag",
|
|
397
|
+
type: "primary",
|
|
398
|
+
effect: "light",
|
|
399
|
+
onClick: (V) => r(k)
|
|
400
|
+
}, {
|
|
401
|
+
default: d(() => [
|
|
402
|
+
$("span", Ae, [
|
|
403
|
+
y(b, null, {
|
|
404
|
+
default: d(() => [
|
|
405
|
+
y(X(de))
|
|
406
|
+
]),
|
|
407
|
+
_: 1
|
|
408
|
+
}),
|
|
409
|
+
$("span", Fe, F(k.name), 1)
|
|
410
|
+
])
|
|
411
|
+
]),
|
|
412
|
+
_: 2
|
|
413
|
+
}, 1032, ["onClick"]))), 128))
|
|
414
|
+
])
|
|
415
|
+
])
|
|
416
|
+
]);
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
}), Pe = /* @__PURE__ */ q(Me, [["__scopeId", "data-v-5468ee4e"]]), Ie = {
|
|
420
|
+
key: 0,
|
|
421
|
+
class: "schema-preview-container"
|
|
422
|
+
}, Be = { class: "custom-header" }, Ee = ["id"], Re = { class: "header-controls" }, Le = { class: "preview-content" }, Ke = { class: "preview-content" }, je = /* @__PURE__ */ j({
|
|
423
|
+
__name: "SchemaPreview",
|
|
424
|
+
props: {
|
|
425
|
+
schema: {},
|
|
426
|
+
modelValue: { type: Boolean },
|
|
427
|
+
file: {}
|
|
428
|
+
},
|
|
429
|
+
emits: ["update:modelValue"],
|
|
430
|
+
setup(e, { emit: r }) {
|
|
431
|
+
const t = e, v = r, b = C(!1), s = D({
|
|
432
|
+
get: () => t.modelValue,
|
|
433
|
+
set: (g) => {
|
|
434
|
+
v("update:modelValue", g), g || setTimeout(() => {
|
|
435
|
+
b.value = !1;
|
|
436
|
+
}, 300);
|
|
437
|
+
}
|
|
438
|
+
}), k = () => {
|
|
439
|
+
b.value = !b.value;
|
|
440
|
+
};
|
|
441
|
+
return ee(() => t.schema.fullscreen, (g) => {
|
|
442
|
+
g !== void 0 && (b.value = g);
|
|
443
|
+
}, { immediate: !0 }), (g, V) => {
|
|
444
|
+
const N = h("el-icon"), U = h("el-button"), T = h("el-dialog"), A = h("el-drawer");
|
|
445
|
+
return s.value ? (a(), S("div", Ie, [
|
|
446
|
+
e.schema.mode === "dialog" ? (a(), p(T, {
|
|
447
|
+
key: 0,
|
|
448
|
+
modelValue: s.value,
|
|
449
|
+
"onUpdate:modelValue": V[0] || (V[0] = (l) => s.value = l),
|
|
450
|
+
width: e.schema.width,
|
|
451
|
+
fullscreen: b.value || e.schema.fullscreen,
|
|
452
|
+
draggable: "",
|
|
453
|
+
"destroy-on-close": "",
|
|
454
|
+
"append-to-body": "",
|
|
455
|
+
class: "preview-dialog",
|
|
456
|
+
"show-close": !1
|
|
457
|
+
}, {
|
|
458
|
+
header: d(({ close: l, titleId: _, titleClass: z }) => [
|
|
459
|
+
$("div", Be, [
|
|
460
|
+
$("span", {
|
|
461
|
+
id: _,
|
|
462
|
+
class: ce(z)
|
|
463
|
+
}, F(e.schema.dialogTitle || "预览"), 11, Ee),
|
|
464
|
+
$("div", Re, [
|
|
465
|
+
y(U, {
|
|
466
|
+
link: "",
|
|
467
|
+
onClick: k
|
|
468
|
+
}, {
|
|
469
|
+
default: d(() => [
|
|
470
|
+
y(N, null, {
|
|
471
|
+
default: d(() => [
|
|
472
|
+
(a(), p(O(b.value ? "CopyDocument" : "FullScreen")))
|
|
473
|
+
]),
|
|
474
|
+
_: 1
|
|
475
|
+
})
|
|
476
|
+
]),
|
|
477
|
+
_: 1
|
|
478
|
+
}),
|
|
479
|
+
y(U, {
|
|
480
|
+
link: "",
|
|
481
|
+
onClick: l
|
|
482
|
+
}, {
|
|
483
|
+
default: d(() => [
|
|
484
|
+
y(N, null, {
|
|
485
|
+
default: d(() => [
|
|
486
|
+
y(X(me))
|
|
487
|
+
]),
|
|
488
|
+
_: 1
|
|
489
|
+
})
|
|
490
|
+
]),
|
|
491
|
+
_: 1
|
|
492
|
+
}, 8, ["onClick"])
|
|
493
|
+
])
|
|
494
|
+
])
|
|
495
|
+
]),
|
|
496
|
+
default: d(() => [
|
|
497
|
+
$("div", Le, [
|
|
498
|
+
e.file ? (a(), p(X(J), {
|
|
499
|
+
key: 0,
|
|
500
|
+
url: e.file.url,
|
|
501
|
+
type: e.file.type,
|
|
502
|
+
name: e.file.name
|
|
503
|
+
}, null, 8, ["url", "type", "name"])) : w("", !0)
|
|
504
|
+
])
|
|
505
|
+
]),
|
|
506
|
+
_: 1
|
|
507
|
+
}, 8, ["modelValue", "width", "fullscreen"])) : (a(), p(A, {
|
|
508
|
+
key: 1,
|
|
509
|
+
modelValue: s.value,
|
|
510
|
+
"onUpdate:modelValue": V[1] || (V[1] = (l) => s.value = l),
|
|
511
|
+
title: e.schema.dialogTitle || "预览",
|
|
512
|
+
size: e.schema.width,
|
|
513
|
+
"destroy-on-close": "",
|
|
514
|
+
"append-to-body": ""
|
|
515
|
+
}, {
|
|
516
|
+
default: d(() => [
|
|
517
|
+
$("div", Ke, [
|
|
518
|
+
e.file ? (a(), p(X(J), {
|
|
519
|
+
key: 0,
|
|
520
|
+
url: e.file.url,
|
|
521
|
+
type: e.file.type,
|
|
522
|
+
name: e.file.name
|
|
523
|
+
}, null, 8, ["url", "type", "name"])) : w("", !0)
|
|
524
|
+
])
|
|
525
|
+
]),
|
|
526
|
+
_: 1
|
|
527
|
+
}, 8, ["modelValue", "title", "size"]))
|
|
528
|
+
])) : w("", !0);
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
}), qe = /* @__PURE__ */ q(je, [["__scopeId", "data-v-caf5bb4b"]]), Oe = { class: "tree-upload-container" }, We = { class: "content-pane" }, Xe = {
|
|
532
|
+
key: 0,
|
|
533
|
+
class: "top-section"
|
|
534
|
+
}, Ye = { class: "table-section" }, Ge = { class: "dialog-footer" }, He = /* @__PURE__ */ j({
|
|
535
|
+
__name: "TreeUpload",
|
|
536
|
+
props: {
|
|
537
|
+
schema: {},
|
|
538
|
+
mode: { default: "edit" }
|
|
539
|
+
},
|
|
540
|
+
setup(e) {
|
|
541
|
+
const r = e, t = C(null), v = C([]), b = C(!1), s = C(null), k = C(!1), g = C("addRoot"), V = G({ label: "" }), N = C(), U = C(null), T = G({
|
|
542
|
+
variables: {
|
|
543
|
+
...r.schema.context?.variables,
|
|
544
|
+
currentNode: void 0,
|
|
545
|
+
currentFile: void 0
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
re("schemaContext", T);
|
|
549
|
+
const A = D(() => {
|
|
550
|
+
const u = r.schema.tree.ui?.width;
|
|
551
|
+
return typeof u == "number" ? `${u}px` : u || "260px";
|
|
552
|
+
}), l = D(() => t.value?.meta?.templates || []), _ = D(() => t.value ? Y("upload", r.schema) : !1), z = D(() => {
|
|
553
|
+
switch (g.value) {
|
|
554
|
+
case "addRoot":
|
|
555
|
+
return "添加根节点";
|
|
556
|
+
case "addChild":
|
|
557
|
+
return "添加子节点";
|
|
558
|
+
case "addSibling":
|
|
559
|
+
return "添加本级节点";
|
|
560
|
+
case "edit":
|
|
561
|
+
return "编辑节点";
|
|
562
|
+
default:
|
|
563
|
+
return "节点操作";
|
|
564
|
+
}
|
|
565
|
+
}), c = (u) => {
|
|
566
|
+
if (console.log("Node Selected:", u), t.value = u, T.variables && (T.variables.currentNode = u), r.schema.table.dataSource.type === "static") {
|
|
567
|
+
const i = r.schema.table.dataSource.data;
|
|
568
|
+
v.value = i.filter((m) => m.meta?.nodeId === String(u.id));
|
|
569
|
+
}
|
|
570
|
+
}, n = (u, i) => {
|
|
571
|
+
if (console.log("Tree Action:", u, i), !Y(u, r.schema)) {
|
|
572
|
+
alert("Permission Denied");
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (r.schema.tree.dataSource.type !== "static") {
|
|
576
|
+
alert(`Action ${u} triggered (API implementation required)`);
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (u === "delete") {
|
|
580
|
+
if (!i || !confirm(`确定删除节点 "${i.label}" 吗?`)) return;
|
|
581
|
+
const m = r.schema.tree.dataSource.data, o = (f) => {
|
|
582
|
+
const M = f.findIndex((P) => P.id === i.id);
|
|
583
|
+
if (M > -1)
|
|
584
|
+
return f.splice(M, 1), !0;
|
|
585
|
+
for (const P of f)
|
|
586
|
+
if (P.children && o(P.children)) return !0;
|
|
587
|
+
return !1;
|
|
588
|
+
};
|
|
589
|
+
o(m) && t.value?.id === i.id && (t.value = null);
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
(u === "addRoot" || u === "addChild" || u === "addSibling" || u === "edit") && (g.value = u, U.value = i, V.label = u === "edit" && i ? i.label : "", k.value = !0, ue(() => {
|
|
593
|
+
N.value?.clearValidate();
|
|
594
|
+
}));
|
|
595
|
+
}, x = () => {
|
|
596
|
+
N.value?.validate((u) => {
|
|
597
|
+
if (!u || r.schema.tree.dataSource.type !== "static")
|
|
598
|
+
return;
|
|
599
|
+
const i = r.schema.tree.dataSource.data, m = V.label, o = g.value, f = U.value;
|
|
600
|
+
if (o === "addRoot")
|
|
601
|
+
i.push({ id: String(Date.now()), label: m, children: [] });
|
|
602
|
+
else if (o === "addChild")
|
|
603
|
+
f && (f.children || (f.children = []), f.children.push({ id: String(Date.now()), label: m, children: [] }));
|
|
604
|
+
else if (o === "addSibling") {
|
|
605
|
+
if (f) {
|
|
606
|
+
const M = (P) => {
|
|
607
|
+
const I = P.findIndex((W) => W.id === f.id);
|
|
608
|
+
if (I > -1)
|
|
609
|
+
return P.splice(I + 1, 0, { id: String(Date.now()), label: m, children: [] }), !0;
|
|
610
|
+
for (const W of P)
|
|
611
|
+
if (W.children && M(W.children)) return !0;
|
|
612
|
+
return !1;
|
|
613
|
+
};
|
|
614
|
+
M(i);
|
|
615
|
+
}
|
|
616
|
+
} else o === "edit" && f && (f.label = m);
|
|
617
|
+
k.value = !1;
|
|
618
|
+
});
|
|
619
|
+
}, B = (u) => {
|
|
620
|
+
if (console.log("Upload Success:", u), r.schema.table.dataSource.type === "static" && t.value) {
|
|
621
|
+
const i = {
|
|
622
|
+
id: Date.now(),
|
|
623
|
+
name: "Uploaded File.png",
|
|
624
|
+
size: 1024,
|
|
625
|
+
url: "#",
|
|
626
|
+
type: "png",
|
|
627
|
+
meta: { nodeId: String(t.value.id) }
|
|
628
|
+
};
|
|
629
|
+
r.schema.table.dataSource.data.push(i), c(t.value);
|
|
630
|
+
}
|
|
631
|
+
}, L = (u, i) => {
|
|
632
|
+
if (console.log("Table Action:", u, i), T.variables && (T.variables.currentFile = i), !Y(u, r.schema)) {
|
|
633
|
+
alert("Permission Denied");
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
if (u === "preview")
|
|
637
|
+
s.value = i, b.value = !0;
|
|
638
|
+
else if (u === "delete" && r.schema.table.dataSource.type === "static") {
|
|
639
|
+
const m = r.schema.table.dataSource.data.findIndex((o) => o.id === i.id);
|
|
640
|
+
m > -1 && (r.schema.table.dataSource.data.splice(m, 1), t.value && c(t.value));
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
return (u, i) => {
|
|
644
|
+
const m = h("el-input"), o = h("el-form-item"), f = h("el-form"), M = h("el-button"), P = h("el-dialog");
|
|
645
|
+
return a(), S("div", Oe, [
|
|
646
|
+
$("div", {
|
|
647
|
+
class: "tree-pane",
|
|
648
|
+
style: Q({ width: A.value })
|
|
649
|
+
}, [
|
|
650
|
+
y(_e, {
|
|
651
|
+
schema: e.schema.tree,
|
|
652
|
+
onNodeClick: c,
|
|
653
|
+
onAction: n
|
|
654
|
+
}, null, 8, ["schema"])
|
|
655
|
+
], 4),
|
|
656
|
+
$("div", We, [
|
|
657
|
+
e.mode === "edit" ? (a(), S("div", Xe, [
|
|
658
|
+
l.value && l.value.length > 0 ? (a(), p(Pe, {
|
|
659
|
+
key: 0,
|
|
660
|
+
templates: l.value
|
|
661
|
+
}, null, 8, ["templates"])) : w("", !0),
|
|
662
|
+
e.schema.upload ? (a(), p(we, {
|
|
663
|
+
key: 1,
|
|
664
|
+
schema: e.schema.upload,
|
|
665
|
+
disabled: !_.value,
|
|
666
|
+
onUploadSuccess: B
|
|
667
|
+
}, null, 8, ["schema", "disabled"])) : w("", !0)
|
|
668
|
+
])) : w("", !0),
|
|
669
|
+
$("div", Ye, [
|
|
670
|
+
y(Te, {
|
|
671
|
+
schema: e.schema.table,
|
|
672
|
+
files: v.value,
|
|
673
|
+
onAction: L
|
|
674
|
+
}, null, 8, ["schema", "files"])
|
|
675
|
+
])
|
|
676
|
+
]),
|
|
677
|
+
e.schema.preview ? (a(), p(qe, {
|
|
678
|
+
key: 0,
|
|
679
|
+
modelValue: b.value,
|
|
680
|
+
"onUpdate:modelValue": i[0] || (i[0] = (I) => b.value = I),
|
|
681
|
+
schema: e.schema.preview,
|
|
682
|
+
file: s.value
|
|
683
|
+
}, null, 8, ["modelValue", "schema", "file"])) : w("", !0),
|
|
684
|
+
y(P, {
|
|
685
|
+
modelValue: k.value,
|
|
686
|
+
"onUpdate:modelValue": i[3] || (i[3] = (I) => k.value = I),
|
|
687
|
+
title: z.value,
|
|
688
|
+
width: "400px",
|
|
689
|
+
"append-to-body": "",
|
|
690
|
+
"destroy-on-close": ""
|
|
691
|
+
}, {
|
|
692
|
+
footer: d(() => [
|
|
693
|
+
$("span", Ge, [
|
|
694
|
+
y(M, {
|
|
695
|
+
onClick: i[2] || (i[2] = (I) => k.value = !1)
|
|
696
|
+
}, {
|
|
697
|
+
default: d(() => [...i[4] || (i[4] = [
|
|
698
|
+
R("取消", -1)
|
|
699
|
+
])]),
|
|
700
|
+
_: 1
|
|
701
|
+
}),
|
|
702
|
+
y(M, {
|
|
703
|
+
type: "primary",
|
|
704
|
+
onClick: x
|
|
705
|
+
}, {
|
|
706
|
+
default: d(() => [...i[5] || (i[5] = [
|
|
707
|
+
R("确定", -1)
|
|
708
|
+
])]),
|
|
709
|
+
_: 1
|
|
710
|
+
})
|
|
711
|
+
])
|
|
712
|
+
]),
|
|
713
|
+
default: d(() => [
|
|
714
|
+
y(f, {
|
|
715
|
+
model: V,
|
|
716
|
+
ref_key: "nodeFormRef",
|
|
717
|
+
ref: N,
|
|
718
|
+
"label-width": "80px"
|
|
719
|
+
}, {
|
|
720
|
+
default: d(() => [
|
|
721
|
+
y(o, {
|
|
722
|
+
label: "节点名称",
|
|
723
|
+
prop: "label",
|
|
724
|
+
rules: [{ required: !0, message: "请输入节点名称", trigger: "blur" }]
|
|
725
|
+
}, {
|
|
726
|
+
default: d(() => [
|
|
727
|
+
y(m, {
|
|
728
|
+
modelValue: V.label,
|
|
729
|
+
"onUpdate:modelValue": i[1] || (i[1] = (I) => V.label = I),
|
|
730
|
+
placeholder: "请输入节点名称"
|
|
731
|
+
}, null, 8, ["modelValue"])
|
|
732
|
+
]),
|
|
733
|
+
_: 1
|
|
734
|
+
})
|
|
735
|
+
]),
|
|
736
|
+
_: 1
|
|
737
|
+
}, 8, ["model"])
|
|
738
|
+
]),
|
|
739
|
+
_: 1
|
|
740
|
+
}, 8, ["modelValue", "title"])
|
|
741
|
+
]);
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
}), tt = /* @__PURE__ */ q(He, [["__scopeId", "data-v-346b7c9b"]]);
|
|
745
|
+
export {
|
|
746
|
+
tt as TreeUpload,
|
|
747
|
+
tt as default
|
|
748
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(V,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("element-plus"),require("@element-plus/icons-vue"),require("file-preview-vue3-ts")):typeof define=="function"&&define.amd?define(["exports","vue","element-plus","@element-plus/icons-vue","file-preview-vue3-ts"],e):(V=typeof globalThis<"u"?globalThis:V||self,e(V.TreeUploadVue3={},V.Vue,V.ElementPlus,V.ElementPlusIconsVue,V.FilePreviewVue3Ts))})(this,(function(V,e,U,A,M){"use strict";const L={class:"schema-tree"},R={key:0,class:"tree-toolbar"},j={class:"custom-tree-node"},q={key:0,class:"actions"},K=["onClick"],O=e.defineComponent({__name:"SchemaTree",props:{schema:{}},emits:["node-click","action"],setup(t,{emit:s}){const o=t,f=s,h=e.ref(),r=e.ref(!1),g=e.ref({x:0,y:0}),u=e.ref(null),C=e.computed(()=>o.schema.dataSource.type==="static"?o.schema.dataSource.data:[]),x={label:o.schema.labelKey||"label",children:o.schema.childrenKey||"children"},B=e.computed(()=>o.schema.actions?.filter(n=>n.position==="toolbar")||[]),b=e.computed(()=>o.schema.actions?.filter(n=>n.position==="node")||[]),N=e.computed(()=>o.schema.actions?.filter(n=>n.position==="contextMenu")||[]),l=n=>{r.value=!1,f("node-click",n)},k=(n,y)=>{N.value.length!==0&&(n.preventDefault(),r.value=!0,g.value={x:n.clientX,y:n.clientY},u.value=y)},_=(n,y)=>{r.value=!1,!(n.confirm&&!confirm(n.confirm.message||"Are you sure?"))&&f("action",n.key,y)},i=()=>{r.value=!1};return e.onMounted(()=>{document.addEventListener("click",i)}),e.onUnmounted(()=>{document.removeEventListener("click",i)}),(n,y)=>{const $=e.resolveComponent("el-icon"),D=e.resolveComponent("el-button"),d=e.resolveComponent("el-tooltip"),c=e.resolveComponent("el-tree");return e.openBlock(),e.createElementBlock("div",L,[B.value.length?(e.openBlock(),e.createElementBlock("div",R,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(B.value,m=>(e.openBlock(),e.createBlock(D,{key:m.key,type:"primary",link:"",onClick:a=>_(m,null)},{default:e.withCtx(()=>[m.icon?(e.openBlock(),e.createBlock($,{key:0},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(m.icon)))]),_:2},1024)):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(m.label),1)]),_:2},1032,["onClick"]))),128))])):e.createCommentVNode("",!0),e.createVNode(c,{ref_key:"treeRef",ref:h,data:C.value,"node-key":t.schema.nodeKey||"id",props:x,"default-expand-all":t.schema.ui?.defaultExpandAll,"highlight-current":t.schema.ui?.highlightCurrent,"expand-on-click-node":!1,onNodeClick:l,onNodeContextmenu:k},{default:e.withCtx(({node:m,data:a})=>[e.createElementVNode("span",j,[e.createElementVNode("span",null,e.toDisplayString(m.label),1),b.value.length?(e.openBlock(),e.createElementBlock("span",q,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(b.value,p=>(e.openBlock(),e.createBlock(d,{key:p.key,content:p.label,placement:"top","show-after":200},{default:e.withCtx(()=>[e.createVNode(D,{link:"",type:"primary",onClick:e.withModifiers(w=>_(p,a),["stop"])},{default:e.withCtx(()=>[p.icon?(e.openBlock(),e.createBlock($,{key:0},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(p.icon)))]),_:2},1024)):e.createCommentVNode("",!0)]),_:2},1032,["onClick"])]),_:2},1032,["content"]))),128))])):e.createCommentVNode("",!0)])]),_:1},8,["data","node-key","default-expand-all","highlight-current"]),r.value?(e.openBlock(),e.createElementBlock("div",{key:1,class:"context-menu",style:e.normalizeStyle({left:g.value.x+"px",top:g.value.y+"px"})},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(N.value,m=>(e.openBlock(),e.createElementBlock("div",{key:m.key,class:"context-menu-item",onClick:a=>_(m,u.value)},[m.icon?(e.openBlock(),e.createBlock($,{key:0},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(m.icon)))]),_:2},1024)):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(m.label),1)],8,K))),128))],4)):e.createCommentVNode("",!0)])}}}),T=(t,s)=>{const o=t.__vccOpts||t;for(const[f,h]of s)o[f]=h;return o},W=T(O,[["__scopeId","data-v-493d816e"]]);function F(t,s,o){return s.permissions?s.permissions.default?.[t]!==!1:!0}function P(t,s){if(!t)return t;let o=t;const f=s.variables||{};return f.currentNode&&(o=o.replace(/\$currentNode\.id/g,String(f.currentNode.id)),o=o.replace(/\$currentNode\.label/g,f.currentNode.label)),o}const X={key:0,class:"schema-upload"},Y={class:"el-upload__text"},G={class:"el-upload__tip"},H=T(e.defineComponent({__name:"SchemaUpload",props:{schema:{},disabled:{type:Boolean}},emits:["upload-success","upload-error"],setup(t,{emit:s}){const o=t,f=s,h=e.inject("schemaContext",{}),r=e.computed(()=>{const l=h.variables?.currentNode?.meta?.upload||{};return{...o.schema,...l,limit:l.limit??o.schema.limit,maxSize:l.maxSize,minLimit:l.minLimit,accept:l.accept??o.schema.accept,multiple:l.multiple??o.schema.multiple,drag:l.drag??o.schema.drag,autoUpload:l.autoUpload??o.schema.autoUpload}}),g=e.computed(()=>o.schema.headers||{}),u=e.computed(()=>{const l=o.schema.data||{},k={};for(const _ in l){const i=l[_];typeof i=="string"?k[_]=P(i,h):k[_]=i}return k}),C=e.computed(()=>{let l=o.schema.ui?.tipText||"";const k=[];if(r.value.maxSize){const _=(r.value.maxSize/1024/1024).toFixed(1);k.push(`大小限制 ${_}MB`)}return r.value.limit&&k.push(`数量限制 ${r.value.limit}个`),r.value.accept&&k.push(`格式 ${r.value.accept}`),k.length?`${l} (${k.join(", ")})`:l}),x=l=>{const k=r.value.maxSize;return k&&l.size>k?(U.ElMessage.error(`文件大小不能超过 ${(k/1024/1024).toFixed(1)}MB!`),!1):!0},B=()=>{U.ElMessage.warning(`当前限制选择 ${r.value.limit} 个文件`)},b=l=>{f("upload-success",l)},N=l=>{f("upload-error",l)};return(l,k)=>{const _=e.resolveComponent("upload-filled"),i=e.resolveComponent("el-icon"),n=e.resolveComponent("el-button"),y=e.resolveComponent("el-upload");return t.schema.enabled?(e.openBlock(),e.createElementBlock("div",X,[e.createVNode(y,{class:"upload-demo",action:t.schema.action,method:t.schema.method||"post",headers:g.value,data:u.value,multiple:r.value.multiple,drag:r.value.drag,accept:r.value.accept,limit:r.value.limit,"auto-upload":r.value.autoUpload!==!1,disabled:t.disabled,"show-file-list":t.schema.ui?.showFileList,"before-upload":x,"on-exceed":B,onSuccess:b,onError:N},e.createSlots({default:e.withCtx(()=>[r.value.drag?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(i,{class:"el-icon--upload"},{default:e.withCtx(()=>[e.createVNode(_)]),_:1}),e.createElementVNode("div",Y,e.toDisplayString(t.schema.ui?.buttonText||"Drop file here or click to upload"),1)],64)):e.createCommentVNode("",!0)]),_:2},[r.value.drag?void 0:{name:"trigger",fn:e.withCtx(()=>[e.createVNode(n,{type:"primary"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.schema.ui?.buttonText||"Click to upload"),1)]),_:1})]),key:"0"},t.schema.ui?.showTip?{name:"tip",fn:e.withCtx(()=>[e.createElementVNode("div",G,e.toDisplayString(C.value),1)]),key:"1"}:void 0]),1032,["action","method","headers","data","multiple","drag","accept","limit","auto-upload","disabled","show-file-list"])])):e.createCommentVNode("",!0)}}}),[["__scopeId","data-v-b2da1f5f"]]),J={class:"schema-table"},Q={key:0,class:"table-toolbar"},Z={key:1,class:"pagination-wrapper"},v=T(e.defineComponent({__name:"SchemaTable",props:{schema:{},files:{}},emits:["action","refresh"],setup(t,{emit:s}){const o=t,f=s,h=e.inject("schemaContext",{}),r=e.ref(!1),g=e.ref(1),u=e.ref(o.schema.ui?.pagination?.pageSize||20),C=e.ref(0),x=e.ref([]),B=e.computed(()=>o.files?o.files:o.schema.dataSource.type==="static"?o.schema.dataSource.data:x.value),b=(i,n)=>{if(!n)return i;if(n==="fileSize"){const y=Number(i);return isNaN(y)?i:y<1024?y+" B":y<1024*1024?(y/1024).toFixed(2)+" KB":(y/1024/1024).toFixed(2)+" MB"}return i},N=(i,n)=>{i.confirm&&!confirm(i.confirm.message||"Are you sure?")||f("action",i.key,n)},l=async()=>{if(o.schema.dataSource.type==="api"){r.value=!0;try{const i=o.schema.dataSource,n={...i.params};o.schema.ui?.pagination?.enabled&&(n.page=g.value,n.pageSize=u.value);for(const y in n)typeof n[y]=="string"&&(n[y]=P(n[y],h));console.log("Fetching Table Data:",i.url,n),i.url}catch(i){console.error(i)}finally{r.value=!1}}},k=i=>{u.value=i,l()},_=i=>{g.value=i,l()};return e.watch(()=>h.variables?.currentNode,i=>{i&&o.schema.dataSource.type==="api"&&l()},{deep:!0}),(i,n)=>{const y=e.resolveComponent("el-icon"),$=e.resolveComponent("el-button"),D=e.resolveComponent("el-table-column"),d=e.resolveComponent("el-table"),c=e.resolveComponent("el-pagination"),m=e.resolveDirective("loading");return e.openBlock(),e.createElementBlock("div",J,[t.schema.toolbarActions?.length?(e.openBlock(),e.createElementBlock("div",Q,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.schema.toolbarActions,a=>(e.openBlock(),e.createBlock($,{key:a.key,type:a.type||"default",onClick:p=>N(a,null)},{default:e.withCtx(()=>[a.icon?(e.openBlock(),e.createBlock(y,{key:0},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(a.icon)))]),_:2},1024)):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(a.label),1)]),_:2},1032,["type","onClick"]))),128))])):e.createCommentVNode("",!0),e.withDirectives((e.openBlock(),e.createBlock(d,{data:B.value,stripe:t.schema.ui?.stripe,border:t.schema.ui?.border,size:t.schema.ui?.size,style:{width:"100%",height:"100%",flex:"1"}},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.schema.columns,a=>(e.openBlock(),e.createBlock(D,{key:a.prop,prop:a.prop,label:a.label,width:a.width,align:a.align,fixed:a.fixed,sortable:a.sortable},{default:e.withCtx(p=>[e.createTextVNode(e.toDisplayString(b(p.row[a.prop],a.formatter)),1)]),_:2},1032,["prop","label","width","align","fixed","sortable"]))),128)),t.schema.actions?.length?(e.openBlock(),e.createBlock(D,{key:0,label:"操作",fixed:"right",width:"200"},{default:e.withCtx(a=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.schema.actions,p=>(e.openBlock(),e.createBlock($,{key:p.key,type:p.type||"primary",link:"",onClick:w=>N(p,a.row)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(p.label),1)]),_:2},1032,["type","onClick"]))),128))]),_:1})):e.createCommentVNode("",!0)]),_:1},8,["data","stripe","border","size"])),[[m,r.value]]),t.schema.ui?.pagination?.enabled?(e.openBlock(),e.createElementBlock("div",Z,[e.createVNode(c,{"current-page":g.value,"onUpdate:currentPage":n[0]||(n[0]=a=>g.value=a),"page-size":u.value,"onUpdate:pageSize":n[1]||(n[1]=a=>u.value=a),"page-sizes":[10,20,50,100],layout:t.schema.ui?.pagination?.layout||"total, sizes, prev, pager, next, jumper",total:C.value,onSizeChange:k,onCurrentChange:_},null,8,["current-page","page-size","layout","total"])])):e.createCommentVNode("",!0)])}}}),[["__scopeId","data-v-d92346a5"]]),ee={class:"schema-template"},te={class:"template-container"},oe={class:"tags-wrapper"},le={class:"tag-content"},ne={class:"tpl-name"},ae=T(e.defineComponent({__name:"SchemaTemplate",props:{templates:{}},setup(t){const s=o=>{window.open(o.url,"_blank")};return(o,f)=>{const h=e.resolveComponent("el-icon"),r=e.resolveComponent("el-tag");return e.openBlock(),e.createElementBlock("div",ee,[e.createElementVNode("div",te,[f[0]||(f[0]=e.createElementVNode("span",{class:"label"},"可用模板:",-1)),e.createElementVNode("div",oe,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.templates,(g,u)=>(e.openBlock(),e.createBlock(r,{key:u,class:"template-tag",type:"primary",effect:"light",onClick:C=>s(g)},{default:e.withCtx(()=>[e.createElementVNode("span",le,[e.createVNode(h,null,{default:e.withCtx(()=>[e.createVNode(e.unref(A.Download))]),_:1}),e.createElementVNode("span",ne,e.toDisplayString(g.name),1)])]),_:2},1032,["onClick"]))),128))])])])}}}),[["__scopeId","data-v-5468ee4e"]]),ce={key:0,class:"schema-preview-container"},re={class:"custom-header"},ie=["id"],se={class:"header-controls"},de={class:"preview-content"},me={class:"preview-content"},pe=T(e.defineComponent({__name:"SchemaPreview",props:{schema:{},modelValue:{type:Boolean},file:{}},emits:["update:modelValue"],setup(t,{emit:s}){const o=t,f=s,h=e.ref(!1),r=e.computed({get:()=>o.modelValue,set:u=>{f("update:modelValue",u),u||setTimeout(()=>{h.value=!1},300)}}),g=()=>{h.value=!h.value};return e.watch(()=>o.schema.fullscreen,u=>{u!==void 0&&(h.value=u)},{immediate:!0}),(u,C)=>{const x=e.resolveComponent("el-icon"),B=e.resolveComponent("el-button"),b=e.resolveComponent("el-dialog"),N=e.resolveComponent("el-drawer");return r.value?(e.openBlock(),e.createElementBlock("div",ce,[t.schema.mode==="dialog"?(e.openBlock(),e.createBlock(b,{key:0,modelValue:r.value,"onUpdate:modelValue":C[0]||(C[0]=l=>r.value=l),width:t.schema.width,fullscreen:h.value||t.schema.fullscreen,draggable:"","destroy-on-close":"","append-to-body":"",class:"preview-dialog","show-close":!1},{header:e.withCtx(({close:l,titleId:k,titleClass:_})=>[e.createElementVNode("div",re,[e.createElementVNode("span",{id:k,class:e.normalizeClass(_)},e.toDisplayString(t.schema.dialogTitle||"预览"),11,ie),e.createElementVNode("div",se,[e.createVNode(B,{link:"",onClick:g},{default:e.withCtx(()=>[e.createVNode(x,null,{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(h.value?"CopyDocument":"FullScreen")))]),_:1})]),_:1}),e.createVNode(B,{link:"",onClick:l},{default:e.withCtx(()=>[e.createVNode(x,null,{default:e.withCtx(()=>[e.createVNode(e.unref(A.Close))]),_:1})]),_:1},8,["onClick"])])])]),default:e.withCtx(()=>[e.createElementVNode("div",de,[t.file?(e.openBlock(),e.createBlock(e.unref(M),{key:0,url:t.file.url,type:t.file.type,name:t.file.name},null,8,["url","type","name"])):e.createCommentVNode("",!0)])]),_:1},8,["modelValue","width","fullscreen"])):(e.openBlock(),e.createBlock(N,{key:1,modelValue:r.value,"onUpdate:modelValue":C[1]||(C[1]=l=>r.value=l),title:t.schema.dialogTitle||"预览",size:t.schema.width,"destroy-on-close":"","append-to-body":""},{default:e.withCtx(()=>[e.createElementVNode("div",me,[t.file?(e.openBlock(),e.createBlock(e.unref(M),{key:0,url:t.file.url,type:t.file.type,name:t.file.name},null,8,["url","type","name"])):e.createCommentVNode("",!0)])]),_:1},8,["modelValue","title","size"]))])):e.createCommentVNode("",!0)}}}),[["__scopeId","data-v-caf5bb4b"]]),fe={class:"tree-upload-container"},he={class:"content-pane"},ue={key:0,class:"top-section"},ke={class:"table-section"},ge={class:"dialog-footer"},I=T(e.defineComponent({__name:"TreeUpload",props:{schema:{},mode:{default:"edit"}},setup(t){const s=t,o=e.ref(null),f=e.ref([]),h=e.ref(!1),r=e.ref(null),g=e.ref(!1),u=e.ref("addRoot"),C=e.reactive({label:""}),x=e.ref(),B=e.ref(null),b=e.reactive({variables:{...s.schema.context?.variables,currentNode:void 0,currentFile:void 0}});e.provide("schemaContext",b);const N=e.computed(()=>{const d=s.schema.tree.ui?.width;return typeof d=="number"?`${d}px`:d||"260px"}),l=e.computed(()=>o.value?.meta?.templates||[]),k=e.computed(()=>o.value?F("upload",s.schema):!1),_=e.computed(()=>{switch(u.value){case"addRoot":return"添加根节点";case"addChild":return"添加子节点";case"addSibling":return"添加本级节点";case"edit":return"编辑节点";default:return"节点操作"}}),i=d=>{if(console.log("Node Selected:",d),o.value=d,b.variables&&(b.variables.currentNode=d),s.schema.table.dataSource.type==="static"){const c=s.schema.table.dataSource.data;f.value=c.filter(m=>m.meta?.nodeId===String(d.id))}},n=(d,c)=>{if(console.log("Tree Action:",d,c),!F(d,s.schema)){alert("Permission Denied");return}if(s.schema.tree.dataSource.type!=="static"){alert(`Action ${d} triggered (API implementation required)`);return}if(d==="delete"){if(!c||!confirm(`确定删除节点 "${c.label}" 吗?`))return;const m=s.schema.tree.dataSource.data,a=p=>{const w=p.findIndex(S=>S.id===c.id);if(w>-1)return p.splice(w,1),!0;for(const S of p)if(S.children&&a(S.children))return!0;return!1};a(m)&&o.value?.id===c.id&&(o.value=null);return}(d==="addRoot"||d==="addChild"||d==="addSibling"||d==="edit")&&(u.value=d,B.value=c,C.label=d==="edit"&&c?c.label:"",g.value=!0,e.nextTick(()=>{x.value?.clearValidate()}))},y=()=>{x.value?.validate(d=>{if(!d||s.schema.tree.dataSource.type!=="static")return;const c=s.schema.tree.dataSource.data,m=C.label,a=u.value,p=B.value;if(a==="addRoot")c.push({id:String(Date.now()),label:m,children:[]});else if(a==="addChild")p&&(p.children||(p.children=[]),p.children.push({id:String(Date.now()),label:m,children:[]}));else if(a==="addSibling"){if(p){const w=S=>{const E=S.findIndex(z=>z.id===p.id);if(E>-1)return S.splice(E+1,0,{id:String(Date.now()),label:m,children:[]}),!0;for(const z of S)if(z.children&&w(z.children))return!0;return!1};w(c)}}else a==="edit"&&p&&(p.label=m);g.value=!1})},$=d=>{if(console.log("Upload Success:",d),s.schema.table.dataSource.type==="static"&&o.value){const c={id:Date.now(),name:"Uploaded File.png",size:1024,url:"#",type:"png",meta:{nodeId:String(o.value.id)}};s.schema.table.dataSource.data.push(c),i(o.value)}},D=(d,c)=>{if(console.log("Table Action:",d,c),b.variables&&(b.variables.currentFile=c),!F(d,s.schema)){alert("Permission Denied");return}if(d==="preview")r.value=c,h.value=!0;else if(d==="delete"&&s.schema.table.dataSource.type==="static"){const m=s.schema.table.dataSource.data.findIndex(a=>a.id===c.id);m>-1&&(s.schema.table.dataSource.data.splice(m,1),o.value&&i(o.value))}};return(d,c)=>{const m=e.resolveComponent("el-input"),a=e.resolveComponent("el-form-item"),p=e.resolveComponent("el-form"),w=e.resolveComponent("el-button"),S=e.resolveComponent("el-dialog");return e.openBlock(),e.createElementBlock("div",fe,[e.createElementVNode("div",{class:"tree-pane",style:e.normalizeStyle({width:N.value})},[e.createVNode(W,{schema:t.schema.tree,onNodeClick:i,onAction:n},null,8,["schema"])],4),e.createElementVNode("div",he,[t.mode==="edit"?(e.openBlock(),e.createElementBlock("div",ue,[l.value&&l.value.length>0?(e.openBlock(),e.createBlock(ae,{key:0,templates:l.value},null,8,["templates"])):e.createCommentVNode("",!0),t.schema.upload?(e.openBlock(),e.createBlock(H,{key:1,schema:t.schema.upload,disabled:!k.value,onUploadSuccess:$},null,8,["schema","disabled"])):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),e.createElementVNode("div",ke,[e.createVNode(v,{schema:t.schema.table,files:f.value,onAction:D},null,8,["schema","files"])])]),t.schema.preview?(e.openBlock(),e.createBlock(pe,{key:0,modelValue:h.value,"onUpdate:modelValue":c[0]||(c[0]=E=>h.value=E),schema:t.schema.preview,file:r.value},null,8,["modelValue","schema","file"])):e.createCommentVNode("",!0),e.createVNode(S,{modelValue:g.value,"onUpdate:modelValue":c[3]||(c[3]=E=>g.value=E),title:_.value,width:"400px","append-to-body":"","destroy-on-close":""},{footer:e.withCtx(()=>[e.createElementVNode("span",ge,[e.createVNode(w,{onClick:c[2]||(c[2]=E=>g.value=!1)},{default:e.withCtx(()=>[...c[4]||(c[4]=[e.createTextVNode("取消",-1)])]),_:1}),e.createVNode(w,{type:"primary",onClick:y},{default:e.withCtx(()=>[...c[5]||(c[5]=[e.createTextVNode("确定",-1)])]),_:1})])]),default:e.withCtx(()=>[e.createVNode(p,{model:C,ref_key:"nodeFormRef",ref:x,"label-width":"80px"},{default:e.withCtx(()=>[e.createVNode(a,{label:"节点名称",prop:"label",rules:[{required:!0,message:"请输入节点名称",trigger:"blur"}]},{default:e.withCtx(()=>[e.createVNode(m,{modelValue:C.label,"onUpdate:modelValue":c[1]||(c[1]=E=>C.label=E),placeholder:"请输入节点名称"},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["modelValue","title"])])}}}),[["__scopeId","data-v-346b7c9b"]]);V.TreeUpload=I,V.default=I,Object.defineProperties(V,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export interface TreeUploadSchema {
|
|
2
|
+
version: string;
|
|
3
|
+
context?: SchemaContext;
|
|
4
|
+
tree: TreeSchema;
|
|
5
|
+
upload?: UploadSchema;
|
|
6
|
+
table: TableSchema;
|
|
7
|
+
preview?: PreviewSchema;
|
|
8
|
+
permissions?: PermissionSchema;
|
|
9
|
+
}
|
|
10
|
+
export interface SchemaContext {
|
|
11
|
+
variables?: {
|
|
12
|
+
currentNode?: CategoryNode;
|
|
13
|
+
currentFile?: FileItem;
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface TreeSchema {
|
|
18
|
+
nodeKey?: string;
|
|
19
|
+
labelKey?: string;
|
|
20
|
+
childrenKey?: string;
|
|
21
|
+
dataSource: TreeDataSource;
|
|
22
|
+
ui?: TreeUISchema;
|
|
23
|
+
actions?: TreeActionSchema[];
|
|
24
|
+
}
|
|
25
|
+
export type TreeDataSource = {
|
|
26
|
+
type: 'static';
|
|
27
|
+
data: CategoryNode[];
|
|
28
|
+
} | ({
|
|
29
|
+
type: 'api';
|
|
30
|
+
} & ApiDataSourceBase);
|
|
31
|
+
export interface TreeUISchema {
|
|
32
|
+
showRoot?: boolean;
|
|
33
|
+
defaultExpandAll?: boolean;
|
|
34
|
+
highlightCurrent?: boolean;
|
|
35
|
+
width?: number | string;
|
|
36
|
+
lazy?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface CategoryNode {
|
|
39
|
+
id: string | number;
|
|
40
|
+
label: string;
|
|
41
|
+
children?: CategoryNode[];
|
|
42
|
+
meta?: Record<string, any>;
|
|
43
|
+
}
|
|
44
|
+
export type BuiltinTreeAction = 'add' | 'addRoot' | 'addChild' | 'addSibling' | 'delete' | 'edit' | 'upload' | 'download' | 'preview';
|
|
45
|
+
export type TreeAction = BuiltinTreeAction | `custom:${string}`;
|
|
46
|
+
export interface TreeActionSchema {
|
|
47
|
+
key: TreeAction;
|
|
48
|
+
label: string;
|
|
49
|
+
icon?: string;
|
|
50
|
+
position?: 'node' | 'contextMenu' | 'toolbar';
|
|
51
|
+
confirm?: {
|
|
52
|
+
title?: string;
|
|
53
|
+
message?: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface UploadSchema {
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
action: string;
|
|
59
|
+
method?: 'post' | 'put';
|
|
60
|
+
headers?: Record<string, string>;
|
|
61
|
+
data?: Record<string, any>;
|
|
62
|
+
multiple?: boolean;
|
|
63
|
+
limit?: number;
|
|
64
|
+
accept?: string;
|
|
65
|
+
drag?: boolean;
|
|
66
|
+
autoUpload?: boolean;
|
|
67
|
+
ui?: UploadUISchema;
|
|
68
|
+
}
|
|
69
|
+
export interface UploadUISchema {
|
|
70
|
+
showTip?: boolean;
|
|
71
|
+
tipText?: string;
|
|
72
|
+
buttonText?: string;
|
|
73
|
+
showFileList?: boolean;
|
|
74
|
+
}
|
|
75
|
+
export interface TableSchema {
|
|
76
|
+
rowKey?: string;
|
|
77
|
+
dataSource: TableDataSource;
|
|
78
|
+
columns: TableColumnSchema[];
|
|
79
|
+
actions?: TableActionSchema[];
|
|
80
|
+
toolbarActions?: TableActionSchema[];
|
|
81
|
+
ui?: TableUISchema;
|
|
82
|
+
}
|
|
83
|
+
export type TableDataSource = {
|
|
84
|
+
type: 'static';
|
|
85
|
+
data: FileItem[];
|
|
86
|
+
} | ({
|
|
87
|
+
type: 'api';
|
|
88
|
+
} & ApiDataSourceBase);
|
|
89
|
+
export interface FileItem {
|
|
90
|
+
id: string | number;
|
|
91
|
+
name: string;
|
|
92
|
+
url: string;
|
|
93
|
+
type?: string;
|
|
94
|
+
size?: number;
|
|
95
|
+
meta?: Record<string, any>;
|
|
96
|
+
}
|
|
97
|
+
export interface TableColumnSchema {
|
|
98
|
+
prop: string;
|
|
99
|
+
label: string;
|
|
100
|
+
width?: number | string;
|
|
101
|
+
align?: 'left' | 'center' | 'right';
|
|
102
|
+
formatter?: string;
|
|
103
|
+
sortable?: boolean;
|
|
104
|
+
fixed?: 'left' | 'right';
|
|
105
|
+
}
|
|
106
|
+
export interface TableActionSchema {
|
|
107
|
+
key: TreeAction;
|
|
108
|
+
label: string;
|
|
109
|
+
icon?: string;
|
|
110
|
+
type?: 'primary' | 'success' | 'warning' | 'danger' | 'info';
|
|
111
|
+
confirm?: {
|
|
112
|
+
title?: string;
|
|
113
|
+
message?: string;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export interface TableUISchema {
|
|
117
|
+
stripe?: boolean;
|
|
118
|
+
border?: boolean;
|
|
119
|
+
size?: 'small' | 'default' | 'large';
|
|
120
|
+
pagination?: {
|
|
121
|
+
enabled: boolean;
|
|
122
|
+
pageSize?: number;
|
|
123
|
+
layout?: string;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export interface PreviewSchema {
|
|
127
|
+
enabled?: boolean;
|
|
128
|
+
mode?: 'dialog' | 'drawer';
|
|
129
|
+
dialogTitle?: string;
|
|
130
|
+
width?: string | number;
|
|
131
|
+
height?: string | number;
|
|
132
|
+
fullscreen?: boolean;
|
|
133
|
+
}
|
|
134
|
+
export interface PermissionSchema {
|
|
135
|
+
default?: Partial<Record<TreeAction, boolean>>;
|
|
136
|
+
rules?: PermissionRuleSchema[];
|
|
137
|
+
}
|
|
138
|
+
export interface PermissionRuleSchema {
|
|
139
|
+
action: TreeAction;
|
|
140
|
+
when?: {
|
|
141
|
+
conditions?: ConditionSchema[];
|
|
142
|
+
mode?: 'view' | 'edit';
|
|
143
|
+
};
|
|
144
|
+
allow: boolean;
|
|
145
|
+
}
|
|
146
|
+
export interface ConditionSchema {
|
|
147
|
+
field: string;
|
|
148
|
+
operator: 'eq' | 'neq' | 'in' | 'notIn' | 'exists';
|
|
149
|
+
value?: any;
|
|
150
|
+
}
|
|
151
|
+
export interface ApiDataSourceBase {
|
|
152
|
+
url: string;
|
|
153
|
+
method?: 'get' | 'post';
|
|
154
|
+
params?: Record<string, any>;
|
|
155
|
+
responsePath?: string;
|
|
156
|
+
onError?: 'silent' | 'message' | 'throw';
|
|
157
|
+
loadingKey?: string;
|
|
158
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TreeUploadSchema, TreeAction, SchemaContext } from '../types';
|
|
2
|
+
export declare function checkPermission(action: TreeAction, schema: TreeUploadSchema, context: SchemaContext): boolean;
|
|
3
|
+
export declare function replaceVariables(text: string, context: SchemaContext): string;
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tree-upload-vue3",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "基于 Vue 3 + Element Plus 实现的树形文件管理与上传组件。",
|
|
5
|
+
"main": "dist/tree-upload-vue3.umd.js",
|
|
6
|
+
"module": "dist/tree-upload-vue3.es.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"build": "vue-tsc --noEmit && vite build",
|
|
14
|
+
"preview": "vite preview"
|
|
15
|
+
},
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"element-plus": "^2.0.0",
|
|
18
|
+
"vue": "^3.2.0",
|
|
19
|
+
"@element-plus/icons-vue": "^2.0.0",
|
|
20
|
+
"file-preview-vue3-ts": "*"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@element-plus/icons-vue": "^2.3.2",
|
|
24
|
+
"@types/node": "^25.0.3",
|
|
25
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
26
|
+
"element-plus": "^2.12.0",
|
|
27
|
+
"file-preview-vue3-ts": "^0.0.1",
|
|
28
|
+
"sass": "^1.97.0",
|
|
29
|
+
"typescript": "^5.9.3",
|
|
30
|
+
"vite": "^7.3.0",
|
|
31
|
+
"vite-plugin-dts": "^4.5.4",
|
|
32
|
+
"vue": "^3.5.25",
|
|
33
|
+
"vue-tsc": "^3.1.8"
|
|
34
|
+
}
|
|
35
|
+
}
|