v-nuxt-ui 0.1.32 → 0.1.33
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/module.json +1 -1
- package/dist/runtime/components/form/create-modal-template/index.d.vue.ts +3 -1
- package/dist/runtime/components/form/create-modal-template/index.vue +1 -0
- package/dist/runtime/components/form/create-modal-template/index.vue.d.ts +3 -1
- package/dist/runtime/components/sys/role/CreateModal.vue +14 -2
- package/dist/runtime/components/sys/table/CreateModal.d.vue.ts +13 -0
- package/dist/runtime/components/sys/table/CreateModal.vue +239 -0
- package/dist/runtime/components/sys/table/CreateModal.vue.d.ts +13 -0
- package/dist/runtime/components/sys/table/Table.d.vue.ts +3 -0
- package/dist/runtime/components/sys/table/Table.vue +116 -0
- package/dist/runtime/components/sys/table/Table.vue.d.ts +3 -0
- package/dist/runtime/components/sys/table/TableColumnModal.d.vue.ts +22 -0
- package/dist/runtime/components/sys/table/TableColumnModal.vue +107 -0
- package/dist/runtime/components/sys/table/TableColumnModal.vue.d.ts +22 -0
- package/dist/runtime/components/sys/user/CreateModal.vue +14 -2
- package/dist/runtime/components/table/permission/TablePermissionConfig.d.vue.ts +14 -0
- package/dist/runtime/components/table/permission/TablePermissionConfig.vue +230 -0
- package/dist/runtime/components/table/permission/TablePermissionConfig.vue.d.ts +14 -0
- package/dist/runtime/components/table/permission/TablePermissionTab.d.vue.ts +11 -0
- package/dist/runtime/components/table/permission/TablePermissionTab.vue +95 -0
- package/dist/runtime/components/table/permission/TablePermissionTab.vue.d.ts +11 -0
- package/dist/runtime/components/table/settings/TableSettings.d.vue.ts +3 -0
- package/dist/runtime/components/table/settings/TableSettings.vue +118 -0
- package/dist/runtime/components/table/settings/TableSettings.vue.d.ts +3 -0
- package/dist/runtime/components/table/settings/UserTableColumnModal.d.vue.ts +17 -0
- package/dist/runtime/components/table/settings/UserTableColumnModal.vue +106 -0
- package/dist/runtime/components/table/settings/UserTableColumnModal.vue.d.ts +17 -0
- package/dist/runtime/composables/api/sys/index.d.ts +3 -0
- package/dist/runtime/composables/api/sys/index.js +3 -0
- package/dist/runtime/composables/api/useTableApi.d.ts +2 -0
- package/dist/runtime/composables/api/useTableApi.js +5 -0
- package/dist/runtime/composables/api/useTableColumnApi.d.ts +11 -0
- package/dist/runtime/composables/api/useTableColumnApi.js +11 -0
- package/dist/runtime/composables/api/useTablePermissionApi.d.ts +8 -0
- package/dist/runtime/composables/api/useTablePermissionApi.js +8 -0
- package/dist/runtime/composables/table/useTableColumnPermission.d.ts +34 -0
- package/dist/runtime/composables/table/useTableColumnPermission.js +47 -0
- package/dist/runtime/composables/useAuth.d.ts +56 -0
- package/dist/runtime/composables/useForm.d.ts +1 -1
- package/dist/runtime/composables/useForm.js +7 -3
- package/dist/runtime/types/cmds/sys.d.ts +3 -0
- package/dist/runtime/types/models/index.d.ts +1 -0
- package/dist/runtime/types/models/index.js +1 -0
- package/dist/runtime/types/models/sys.d.ts +3 -0
- package/dist/runtime/types/models/table.d.ts +59 -0
- package/dist/runtime/types/models/table.js +0 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -5,7 +5,9 @@ declare const __VLS_export: <T extends BaseModel>(__VLS_props: NonNullable<Await
|
|
|
5
5
|
} ? P : {});
|
|
6
6
|
expose: (exposed: {}) => void;
|
|
7
7
|
attrs: any;
|
|
8
|
-
slots: {
|
|
8
|
+
slots: {
|
|
9
|
+
'after-form'?: (props: {}) => any;
|
|
10
|
+
};
|
|
9
11
|
emit: {};
|
|
10
12
|
}>) => import("vue").VNode & {
|
|
11
13
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
@@ -5,7 +5,9 @@ declare const __VLS_export: <T extends BaseModel>(__VLS_props: NonNullable<Await
|
|
|
5
5
|
} ? P : {});
|
|
6
6
|
expose: (exposed: {}) => void;
|
|
7
7
|
attrs: any;
|
|
8
|
-
slots: {
|
|
8
|
+
slots: {
|
|
9
|
+
'after-form'?: (props: {}) => any;
|
|
10
|
+
};
|
|
9
11
|
emit: {};
|
|
10
12
|
}>) => import("vue").VNode & {
|
|
11
13
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import FormCreateModalTemplate from "#v/components/form/create-modal-template/index.vue";
|
|
4
|
+
import TablePermissionTab from "#v/components/table/permission/TablePermissionTab.vue";
|
|
4
5
|
import { useFormSubmission, useFormValues, useMenuApi, useRoleApi } from "#v/composables";
|
|
5
6
|
import { computed, onMounted, ref, toRef } from "vue";
|
|
6
7
|
import { treeifyOptions } from "#v/utils";
|
|
@@ -15,7 +16,10 @@ const { onSubmit } = useFormSubmission(
|
|
|
15
16
|
(close) => emit("close", close),
|
|
16
17
|
(model) => emit("save", model),
|
|
17
18
|
useRoleApi,
|
|
18
|
-
["menus"]
|
|
19
|
+
["menus"],
|
|
20
|
+
"id",
|
|
21
|
+
"version",
|
|
22
|
+
() => ({ tablePermissions: tablePermissions.value })
|
|
19
23
|
);
|
|
20
24
|
const menus = ref([]);
|
|
21
25
|
const onFetchMenus = async () => {
|
|
@@ -56,6 +60,7 @@ const targetTreeItems = computed({
|
|
|
56
60
|
function updateTargetTreeItems(newVal) {
|
|
57
61
|
targetTreeItems.value = newVal;
|
|
58
62
|
}
|
|
63
|
+
const tablePermissions = ref(props.model.tablePermissions || []);
|
|
59
64
|
const fields = computed(() => [
|
|
60
65
|
{ name: "name", type: "input", label: "\u89D2\u8272\u540D\u79F0", colSpan: "12", zodType: z.string().min(2, "\u540D\u79F0\u5B57\u6570\u4E0D\u8DB3") },
|
|
61
66
|
{ name: "isAdmin", type: "button-switch", label: "\u662F\u5426\u662F\u7CFB\u7EDF\u89D2\u8272", colSpan: "12", zodType: z.boolean() },
|
|
@@ -88,5 +93,12 @@ onMounted(async () => {
|
|
|
88
93
|
:model-value="newValues"
|
|
89
94
|
@update-model-value="updateModelValue"
|
|
90
95
|
@submit="onSubmit"
|
|
91
|
-
|
|
96
|
+
>
|
|
97
|
+
<template #after-form>
|
|
98
|
+
<div class="border-t pt-4 mt-4">
|
|
99
|
+
<div class="font-semibold mb-2">Table 权限</div>
|
|
100
|
+
<TablePermissionTab v-model="tablePermissions" />
|
|
101
|
+
</div>
|
|
102
|
+
</template>
|
|
103
|
+
</FormCreateModalTemplate>
|
|
92
104
|
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Table } from '#v/types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
model: Table;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
close: (args_0: boolean) => any;
|
|
7
|
+
save: (args_0: Table) => any;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
9
|
+
onClose?: ((args_0: boolean) => any) | undefined;
|
|
10
|
+
onSave?: ((args_0: Table) => any) | undefined;
|
|
11
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
import { useOverlay } from "@nuxt/ui/composables";
|
|
4
|
+
import FormCreateModalTemplate from "#v/components/form/create-modal-template/index.vue";
|
|
5
|
+
import ProSimpleTable from "#v/components/simple-table/index.vue";
|
|
6
|
+
import TableColumnModal from "./TableColumnModal.vue";
|
|
7
|
+
import { useFormSubmission, useFormValues, useTableApi, useTableColumnApi } from "#v/composables";
|
|
8
|
+
import { computed, ref, toRef, onMounted } from "vue";
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
model: { type: Object, required: true }
|
|
11
|
+
});
|
|
12
|
+
const emit = defineEmits(["close", "save"]);
|
|
13
|
+
const overlay = useOverlay();
|
|
14
|
+
const columnModal = overlay.create(TableColumnModal);
|
|
15
|
+
const { oldValues, newValues } = useFormValues(toRef(props.model), { id: 0 });
|
|
16
|
+
const tableColumnApi = useTableColumnApi();
|
|
17
|
+
const columns = ref([]);
|
|
18
|
+
const deletedColumnIds = ref([]);
|
|
19
|
+
const loading = ref(false);
|
|
20
|
+
async function fetchColumns() {
|
|
21
|
+
if (props.model.id === 0) return;
|
|
22
|
+
loading.value = true;
|
|
23
|
+
const { data } = await tableColumnApi.list({
|
|
24
|
+
pagination: { pageNum: 0, pageSize: 0 },
|
|
25
|
+
orderQuery: [{ field: "order", order: "asc" }],
|
|
26
|
+
whereQuery: {
|
|
27
|
+
items: [{ field: "tableId", value: props.model.id, opr: "eq" }]
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
if (data.value.data) {
|
|
31
|
+
columns.value = data.value.data.list.map((col) => ({
|
|
32
|
+
id: col.id,
|
|
33
|
+
columnKey: col.columnKey,
|
|
34
|
+
label: col.label,
|
|
35
|
+
order: col.order,
|
|
36
|
+
width: col.width,
|
|
37
|
+
fixed: col.fixed,
|
|
38
|
+
visible: col.visible
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
loading.value = false;
|
|
42
|
+
}
|
|
43
|
+
onMounted(fetchColumns);
|
|
44
|
+
function addColumn() {
|
|
45
|
+
const maxOrder = columns.value.reduce((max, col) => Math.max(max, col.order ?? 0), 0);
|
|
46
|
+
columns.value.push({
|
|
47
|
+
id: 0,
|
|
48
|
+
columnKey: "",
|
|
49
|
+
label: "",
|
|
50
|
+
order: maxOrder + 1,
|
|
51
|
+
width: 100,
|
|
52
|
+
fixed: "",
|
|
53
|
+
visible: true,
|
|
54
|
+
_isDirty: true
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function removeColumn(index) {
|
|
58
|
+
const col = columns.value[index];
|
|
59
|
+
if (col.id !== 0) {
|
|
60
|
+
deletedColumnIds.value.push(col.id);
|
|
61
|
+
}
|
|
62
|
+
columns.value.splice(index, 1);
|
|
63
|
+
}
|
|
64
|
+
async function editColumn(index) {
|
|
65
|
+
const col = columns.value[index];
|
|
66
|
+
const isNew = col.id === 0;
|
|
67
|
+
if (isNew) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const result = await columnModal.open({ table: props.model, column: col }).result;
|
|
71
|
+
if (result) {
|
|
72
|
+
const updatedCol = result;
|
|
73
|
+
columns.value[index] = { ...updatedCol, _isDirty: true };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const tableColumns = [
|
|
77
|
+
{
|
|
78
|
+
accessorKey: "columnKey",
|
|
79
|
+
header: "\u5217\u6807\u8BC6",
|
|
80
|
+
size: 120
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
accessorKey: "label",
|
|
84
|
+
header: "\u663E\u793A\u540D",
|
|
85
|
+
size: 120
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
accessorKey: "order",
|
|
89
|
+
header: "\u987A\u5E8F",
|
|
90
|
+
size: 80
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
accessorKey: "width",
|
|
94
|
+
header: "\u5BBD\u5EA6",
|
|
95
|
+
size: 80
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
accessorKey: "fixed",
|
|
99
|
+
header: "\u56FA\u5B9A",
|
|
100
|
+
size: 80,
|
|
101
|
+
cell: ({ row }) => {
|
|
102
|
+
const fixedMap = { "": "\u5426", left: "\u5DE6", right: "\u53F3" };
|
|
103
|
+
return fixedMap[row.fixed] ?? "\u5426";
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
accessorKey: "visible",
|
|
108
|
+
header: "\u663E\u793A",
|
|
109
|
+
size: 60,
|
|
110
|
+
cell: ({ row }) => row.visible ? "\u662F" : "\u5426"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
accessorKey: "actions",
|
|
114
|
+
header: "\u64CD\u4F5C",
|
|
115
|
+
size: 100,
|
|
116
|
+
cell: ({ row, index }) => {
|
|
117
|
+
return {
|
|
118
|
+
type: "div",
|
|
119
|
+
class: "flex gap-1",
|
|
120
|
+
children: [
|
|
121
|
+
{
|
|
122
|
+
type: "button",
|
|
123
|
+
label: "\u7F16\u8F91",
|
|
124
|
+
icon: "i-lucide-edit",
|
|
125
|
+
variant: "ghost",
|
|
126
|
+
size: "xs",
|
|
127
|
+
onClick: () => editColumn(index)
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: "button",
|
|
131
|
+
label: "\u5220\u9664",
|
|
132
|
+
icon: "i-lucide-trash-2",
|
|
133
|
+
color: "error",
|
|
134
|
+
variant: "ghost",
|
|
135
|
+
size: "xs",
|
|
136
|
+
onClick: () => removeColumn(index)
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
];
|
|
143
|
+
const { onSubmit } = useFormSubmission(
|
|
144
|
+
toRef(oldValues),
|
|
145
|
+
toRef(newValues),
|
|
146
|
+
(close) => emit("close", close),
|
|
147
|
+
async (model) => {
|
|
148
|
+
const tableApi = useTableApi();
|
|
149
|
+
if (model.id === 0) {
|
|
150
|
+
const { data } = await tableApi.create(model);
|
|
151
|
+
const newTable = data.value?.data;
|
|
152
|
+
if (newTable && columns.value.length > 0) {
|
|
153
|
+
for (const col of columns.value) {
|
|
154
|
+
await tableColumnApi.create({
|
|
155
|
+
...col,
|
|
156
|
+
tableId: newTable.id
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
emit("save", newTable);
|
|
161
|
+
} else {
|
|
162
|
+
for (const col of columns.value) {
|
|
163
|
+
if (col._isDirty) {
|
|
164
|
+
const colData = {
|
|
165
|
+
id: col.id,
|
|
166
|
+
tableId: props.model.id,
|
|
167
|
+
columnKey: col.columnKey,
|
|
168
|
+
label: col.label,
|
|
169
|
+
order: col.order,
|
|
170
|
+
width: col.width,
|
|
171
|
+
fixed: col.fixed,
|
|
172
|
+
visible: col.visible
|
|
173
|
+
};
|
|
174
|
+
if (col.id === 0) {
|
|
175
|
+
await tableColumnApi.create(tableColumnApi.prune(colData));
|
|
176
|
+
} else {
|
|
177
|
+
await tableColumnApi.update(tableColumnApi.prune(colData));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (const id of deletedColumnIds.value) {
|
|
182
|
+
await tableColumnApi.deleteById(id);
|
|
183
|
+
}
|
|
184
|
+
emit("save", model);
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
useTableApi
|
|
188
|
+
);
|
|
189
|
+
const fields = computed(() => [
|
|
190
|
+
{ name: "tblName", type: "input", label: "\u8868\u540D", colSpan: "12", zodType: z.string().min(1, "\u8868\u540D\u4E0D\u80FD\u4E3A\u7A7A") },
|
|
191
|
+
{ name: "label", type: "input", label: "\u663E\u793A\u540D", colSpan: "12", zodType: z.string().min(1, "\u663E\u793A\u540D\u4E0D\u80FD\u4E3A\u7A7A") },
|
|
192
|
+
{ name: "labelI18nKey", type: "input", label: "i18n Key", colSpan: "24", zodType: z.string().optional().nullable() }
|
|
193
|
+
]);
|
|
194
|
+
function updateModelValue(newVal) {
|
|
195
|
+
newValues.value = { id: 0, ...newVal };
|
|
196
|
+
}
|
|
197
|
+
</script>
|
|
198
|
+
|
|
199
|
+
<template>
|
|
200
|
+
<FormCreateModalTemplate
|
|
201
|
+
title="Table"
|
|
202
|
+
:on-close="(ok) => emit('close', ok)"
|
|
203
|
+
:fields="fields"
|
|
204
|
+
:model-value="newValues"
|
|
205
|
+
@update-model-value="updateModelValue"
|
|
206
|
+
@submit="onSubmit"
|
|
207
|
+
>
|
|
208
|
+
<template #after-form>
|
|
209
|
+
<div class="border-t pt-4 mt-4">
|
|
210
|
+
<div class="flex items-center justify-between mb-2">
|
|
211
|
+
<div>
|
|
212
|
+
<div class="font-semibold">列配置</div>
|
|
213
|
+
<div class="text-sm text-dimmed">配置 Table 的列信息</div>
|
|
214
|
+
</div>
|
|
215
|
+
<UButton
|
|
216
|
+
label="添加列"
|
|
217
|
+
icon="i-lucide-plus"
|
|
218
|
+
variant="soft"
|
|
219
|
+
size="sm"
|
|
220
|
+
@click="addColumn"
|
|
221
|
+
/>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
<div v-if="loading" class="py-8 text-center text-dimmed">
|
|
225
|
+
加载中...
|
|
226
|
+
</div>
|
|
227
|
+
<div v-else-if="columns.length === 0" class="py-8 text-center text-dimmed">
|
|
228
|
+
暂无列配置,点击"添加列"创建
|
|
229
|
+
</div>
|
|
230
|
+
<ProSimpleTable
|
|
231
|
+
v-else
|
|
232
|
+
:data="columns"
|
|
233
|
+
:biz-columns="tableColumns"
|
|
234
|
+
class="max-h-64 overflow-y-auto"
|
|
235
|
+
/>
|
|
236
|
+
</div>
|
|
237
|
+
</template>
|
|
238
|
+
</FormCreateModalTemplate>
|
|
239
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Table } from '#v/types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
model: Table;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
close: (args_0: boolean) => any;
|
|
7
|
+
save: (args_0: Table) => any;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
9
|
+
onClose?: ((args_0: boolean) => any) | undefined;
|
|
10
|
+
onSave?: ((args_0: Table) => any) | undefined;
|
|
11
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useOverlay } from "@nuxt/ui/composables";
|
|
3
|
+
import { useTableApi, useTableColumnApi, useTablePermissionApi } from "#v/composables/api";
|
|
4
|
+
import { getOprColumns } from "#v/constants";
|
|
5
|
+
import TablePage from "#v/components/table/Page.vue";
|
|
6
|
+
import CreateModal from "./CreateModal.vue";
|
|
7
|
+
import { h, ref, watch } from "vue";
|
|
8
|
+
const overlay = useOverlay();
|
|
9
|
+
const createModal = overlay.create(CreateModal);
|
|
10
|
+
const tableMeta = ref({});
|
|
11
|
+
const columns = [
|
|
12
|
+
{
|
|
13
|
+
accessorKey: "tblName",
|
|
14
|
+
header: "\u8868\u540D",
|
|
15
|
+
sortOption: true,
|
|
16
|
+
filterOption: {
|
|
17
|
+
type: "input",
|
|
18
|
+
initHide: false
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
accessorKey: "label",
|
|
23
|
+
header: "\u663E\u793A\u540D",
|
|
24
|
+
sortOption: true,
|
|
25
|
+
filterOption: {
|
|
26
|
+
type: "input",
|
|
27
|
+
initHide: false
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
accessorKey: "meta",
|
|
32
|
+
header: "\u5217\u6570",
|
|
33
|
+
cell: ({ row }) => tableMeta.value[row.original.id]?.columnCount ?? "-"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
accessorKey: "permissionCount",
|
|
37
|
+
header: "\u6743\u9650\u6570",
|
|
38
|
+
cell: ({ row }) => tableMeta.value[row.original.id]?.permissionCount ?? "-"
|
|
39
|
+
},
|
|
40
|
+
...getOprColumns()
|
|
41
|
+
];
|
|
42
|
+
const tablePageRef = ref(null);
|
|
43
|
+
async function fetchTableMeta(tables) {
|
|
44
|
+
const tableColumnApi = useTableColumnApi();
|
|
45
|
+
const tablePermissionApi = useTablePermissionApi();
|
|
46
|
+
const newMeta = {};
|
|
47
|
+
await Promise.all(
|
|
48
|
+
tables.map(async (table) => {
|
|
49
|
+
const [columnResult, permissionResult] = await Promise.all([
|
|
50
|
+
tableColumnApi.count({
|
|
51
|
+
whereQuery: {
|
|
52
|
+
items: [{ field: "tableId", value: table.id, opr: "eq" }]
|
|
53
|
+
}
|
|
54
|
+
}),
|
|
55
|
+
tablePermissionApi.count({
|
|
56
|
+
whereQuery: {
|
|
57
|
+
items: [{ field: "tableId", value: table.id, opr: "eq" }]
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
]);
|
|
61
|
+
newMeta[table.id] = {
|
|
62
|
+
columnCount: columnResult.data.value?.data ?? 0,
|
|
63
|
+
permissionCount: permissionResult.data.value?.data ?? 0
|
|
64
|
+
};
|
|
65
|
+
})
|
|
66
|
+
);
|
|
67
|
+
tableMeta.value = { ...tableMeta.value, ...newMeta };
|
|
68
|
+
}
|
|
69
|
+
function getExpandVNode(row) {
|
|
70
|
+
const meta = tableMeta.value[row.id];
|
|
71
|
+
return h("div", { class: "p-4 text-sm text-dimmed" }, [
|
|
72
|
+
h("div", { class: "font-medium mb-2" }, `Table: ${row.tblName}`),
|
|
73
|
+
h("div", {}, `\u663E\u793A\u540D: ${row.label}`),
|
|
74
|
+
h("div", {}, `\u5217\u6570: ${meta?.columnCount ?? "-"}`),
|
|
75
|
+
h("div", {}, `\u6743\u9650\u914D\u7F6E\u6570: ${meta?.permissionCount ?? "-"}`),
|
|
76
|
+
h("div", {}, `\u521B\u5EFA\u65F6\u95F4: ${row.createdAt ? new Date(row.createdAt).toLocaleString() : "-"}`),
|
|
77
|
+
h("div", {}, `\u66F4\u65B0\u65F6\u95F4: ${row.updatedAt ? new Date(row.updatedAt).toLocaleString() : "-"}`)
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
const extraRowActions = [
|
|
81
|
+
{
|
|
82
|
+
label: "\u7F16\u8F91",
|
|
83
|
+
icon: "i-lucide-edit",
|
|
84
|
+
fnWithModal: async (row) => {
|
|
85
|
+
const result = await createModal.open({ model: { ...row } }).result;
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
];
|
|
90
|
+
watch(
|
|
91
|
+
() => tablePageRef.value?.data,
|
|
92
|
+
async (newData) => {
|
|
93
|
+
if (newData && newData.length > 0) {
|
|
94
|
+
await fetchTableMeta(newData);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{ immediate: true }
|
|
98
|
+
);
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<template>
|
|
102
|
+
<TablePage
|
|
103
|
+
ref="tablePageRef"
|
|
104
|
+
name="sys-table"
|
|
105
|
+
cn-name="Table 配置"
|
|
106
|
+
:use-api-group="useTableApi"
|
|
107
|
+
:biz-columns="columns"
|
|
108
|
+
:expandable="true"
|
|
109
|
+
:expand-v-node="getExpandVNode"
|
|
110
|
+
:extra-row-actions="extraRowActions"
|
|
111
|
+
@edit-row-from-modal="async (row) => {
|
|
112
|
+
const result = await createModal.open({ model: { ...row } }).result;
|
|
113
|
+
return result === true;
|
|
114
|
+
}"
|
|
115
|
+
/>
|
|
116
|
+
</template>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TableColumn, Table } from '#v/types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
table: Table;
|
|
4
|
+
column?: {
|
|
5
|
+
id: number;
|
|
6
|
+
columnKey: string;
|
|
7
|
+
label: string;
|
|
8
|
+
order: number;
|
|
9
|
+
width: number;
|
|
10
|
+
fixed: 'left' | 'right' | '';
|
|
11
|
+
visible: boolean;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
15
|
+
close: (args_0: boolean) => any;
|
|
16
|
+
save: (args_0: Partial<TableColumn>) => any;
|
|
17
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
18
|
+
onClose?: ((args_0: boolean) => any) | undefined;
|
|
19
|
+
onSave?: ((args_0: Partial<TableColumn>) => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useTableColumnApi } from "#v/composables/api";
|
|
3
|
+
import { ref } from "vue";
|
|
4
|
+
import { useToast } from "@nuxt/ui/composables";
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
table: { type: Object, required: true },
|
|
7
|
+
column: { type: Object, required: false }
|
|
8
|
+
});
|
|
9
|
+
const emit = defineEmits(["close", "save"]);
|
|
10
|
+
const tableColumnApi = useTableColumnApi();
|
|
11
|
+
const saving = ref(false);
|
|
12
|
+
const formData = ref({
|
|
13
|
+
columnKey: props.column?.columnKey ?? "",
|
|
14
|
+
label: props.column?.label ?? "",
|
|
15
|
+
order: props.column?.order ?? 0,
|
|
16
|
+
width: props.column?.width ?? 100,
|
|
17
|
+
fixed: props.column?.fixed ?? "",
|
|
18
|
+
visible: props.column?.visible ?? true
|
|
19
|
+
});
|
|
20
|
+
async function handleSave() {
|
|
21
|
+
saving.value = true;
|
|
22
|
+
try {
|
|
23
|
+
emit("save", {
|
|
24
|
+
id: props.column?.id,
|
|
25
|
+
columnKey: formData.value.columnKey,
|
|
26
|
+
label: formData.value.label,
|
|
27
|
+
order: formData.value.order,
|
|
28
|
+
width: formData.value.width,
|
|
29
|
+
fixed: formData.value.fixed,
|
|
30
|
+
visible: formData.value.visible
|
|
31
|
+
});
|
|
32
|
+
emit("close", true);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
useToast().add({
|
|
35
|
+
title: "\u4FDD\u5B58\u5931\u8D25",
|
|
36
|
+
description: String(error),
|
|
37
|
+
color: "error",
|
|
38
|
+
icon: "i-lucide-x-circle"
|
|
39
|
+
});
|
|
40
|
+
emit("close", false);
|
|
41
|
+
} finally {
|
|
42
|
+
saving.value = false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template>
|
|
48
|
+
<UModal
|
|
49
|
+
:title="`\u7F16\u8F91\u5217 - ${column?.columnKey ?? ''}`"
|
|
50
|
+
size="md"
|
|
51
|
+
:close="{ onClick: () => emit('close', false) }"
|
|
52
|
+
>
|
|
53
|
+
<div class="p-4 space-y-4">
|
|
54
|
+
<div class="grid grid-cols-2 gap-4">
|
|
55
|
+
<div>
|
|
56
|
+
<label class="text-sm font-medium mb-1 block">列标识</label>
|
|
57
|
+
<UInput v-model="formData.columnKey" placeholder="columnKey" />
|
|
58
|
+
</div>
|
|
59
|
+
<div>
|
|
60
|
+
<label class="text-sm font-medium mb-1 block">显示名</label>
|
|
61
|
+
<UInput v-model="formData.label" placeholder="显示名" />
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="grid grid-cols-3 gap-4">
|
|
65
|
+
<div>
|
|
66
|
+
<label class="text-sm font-medium mb-1 block">顺序</label>
|
|
67
|
+
<UInputNumber v-model="formData.order" :min="0" class="w-full" />
|
|
68
|
+
</div>
|
|
69
|
+
<div>
|
|
70
|
+
<label class="text-sm font-medium mb-1 block">宽度</label>
|
|
71
|
+
<UInputNumber v-model="formData.width" :min="0" class="w-full" />
|
|
72
|
+
</div>
|
|
73
|
+
<div>
|
|
74
|
+
<label class="text-sm font-medium mb-1 block">固定</label>
|
|
75
|
+
<USelect
|
|
76
|
+
v-model="formData.fixed"
|
|
77
|
+
:items="[
|
|
78
|
+
{ label: '\u4E0D\u56FA\u5B9A', value: '' },
|
|
79
|
+
{ label: '\u5DE6\u4FA7', value: 'left' },
|
|
80
|
+
{ label: '\u53F3\u4FA7', value: 'right' }
|
|
81
|
+
]"
|
|
82
|
+
class="w-full"
|
|
83
|
+
/>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="flex items-center gap-2">
|
|
87
|
+
<USwitch v-model="formData.visible" />
|
|
88
|
+
<span class="text-sm">{{ formData.visible ? "\u663E\u793A" : "\u9690\u85CF" }}</span>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
<template #footer>
|
|
92
|
+
<UButton
|
|
93
|
+
label="取消"
|
|
94
|
+
color="neutral"
|
|
95
|
+
variant="subtle"
|
|
96
|
+
@click="emit('close', false)"
|
|
97
|
+
/>
|
|
98
|
+
<UButton
|
|
99
|
+
label="保存"
|
|
100
|
+
color="primary"
|
|
101
|
+
variant="solid"
|
|
102
|
+
:loading="saving"
|
|
103
|
+
@click="handleSave"
|
|
104
|
+
/>
|
|
105
|
+
</template>
|
|
106
|
+
</UModal>
|
|
107
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TableColumn, Table } from '#v/types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
table: Table;
|
|
4
|
+
column?: {
|
|
5
|
+
id: number;
|
|
6
|
+
columnKey: string;
|
|
7
|
+
label: string;
|
|
8
|
+
order: number;
|
|
9
|
+
width: number;
|
|
10
|
+
fixed: 'left' | 'right' | '';
|
|
11
|
+
visible: boolean;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
15
|
+
close: (args_0: boolean) => any;
|
|
16
|
+
save: (args_0: Partial<TableColumn>) => any;
|
|
17
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
18
|
+
onClose?: ((args_0: boolean) => any) | undefined;
|
|
19
|
+
onSave?: ((args_0: Partial<TableColumn>) => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
@@ -3,6 +3,7 @@ import { useFormValues, useFormSubmission, useUserApi, useRoleApi, useMenuApi, u
|
|
|
3
3
|
import { treeifyOptions } from "#v/utils";
|
|
4
4
|
import { toRef, ref, computed, onMounted } from "vue";
|
|
5
5
|
import FormCreateModalTemplate from "#v/components/form/create-modal-template/index.vue";
|
|
6
|
+
import TablePermissionTab from "#v/components/table/permission/TablePermissionTab.vue";
|
|
6
7
|
import { loginTypeOptions, genderOptions, Gender } from "#v/constants";
|
|
7
8
|
import * as z from "zod";
|
|
8
9
|
const props = defineProps({
|
|
@@ -16,7 +17,10 @@ const { onSubmit } = useFormSubmission(
|
|
|
16
17
|
(close) => emit("close", close),
|
|
17
18
|
(model) => emit("save", model),
|
|
18
19
|
useUserApi,
|
|
19
|
-
["roles", "menus"]
|
|
20
|
+
["roles", "menus"],
|
|
21
|
+
"id",
|
|
22
|
+
"version",
|
|
23
|
+
() => ({ tablePermissions: tablePermissions.value })
|
|
20
24
|
);
|
|
21
25
|
const roles = ref([]);
|
|
22
26
|
const onFetchRoles = async () => {
|
|
@@ -103,6 +107,7 @@ const menuTargetTreeItems = computed({
|
|
|
103
107
|
function updateMenuTargetTreeItems(newVal) {
|
|
104
108
|
menuTargetTreeItems.value = newVal;
|
|
105
109
|
}
|
|
110
|
+
const tablePermissions = ref(props.model.tablePermissions || []);
|
|
106
111
|
function updateDepartment(newInitModelValues) {
|
|
107
112
|
newValues.value.department = newInitModelValues;
|
|
108
113
|
}
|
|
@@ -193,5 +198,12 @@ onMounted(async () => {
|
|
|
193
198
|
:model-value="newValues"
|
|
194
199
|
@update-model-value="updateModelValue"
|
|
195
200
|
@submit="onSubmit"
|
|
196
|
-
|
|
201
|
+
>
|
|
202
|
+
<template #after-form>
|
|
203
|
+
<div class="border-t pt-4 mt-4">
|
|
204
|
+
<div class="font-semibold mb-2">Table 权限</div>
|
|
205
|
+
<TablePermissionTab v-model="tablePermissions" />
|
|
206
|
+
</div>
|
|
207
|
+
</template>
|
|
208
|
+
</FormCreateModalTemplate>
|
|
197
209
|
</template>
|