vome-core 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/config/plugin-dev.d.ts +7 -6
- package/dist/admin/config/plugin-dev.js +1 -1
- package/dist/admin/crud/config.js +1 -1
- package/dist/admin/crud/confirm.js +1 -1
- package/dist/admin/crud/dict.js +1 -1
- package/dist/admin/crud/index.d.ts +1 -0
- package/dist/admin/crud/index.js +1 -1
- package/dist/admin/crud/key.js +1 -1
- package/dist/admin/crud/mitt.js +1 -1
- package/dist/admin/crud/plugins.js +1 -1
- package/dist/admin/crud/span.js +1 -1
- package/dist/admin/crud/style.js +1 -1
- package/dist/admin/crud/validate.js +1 -1
- package/dist/admin/crud/vm-dialog.vue +1 -1
- package/dist/admin/crud/vm-export-btn.vue +169 -0
- package/dist/admin/crud/vm-search.vue +18 -3
- package/dist/admin/crud/vm-toolbar.vue +20 -0
- package/dist/admin/crud/vm-upsert.vue +163 -33
- package/dist/admin/directives/perm.js +1 -1
- package/dist/admin/hooks/useUpload.js +1 -1
- package/dist/admin/lib/browser.js +1 -1
- package/dist/admin/lib/cn.js +1 -1
- package/dist/admin/lib/dialog-float.js +1 -1
- package/dist/admin/lib/export-excel.d.ts +11 -0
- package/dist/admin/lib/export-excel.js +1 -0
- package/dist/admin/lib/menu.js +1 -1
- package/dist/admin/lib/tree.js +1 -1
- package/dist/admin/lib/upload.js +1 -1
- package/dist/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/shared/excel.d.ts +13 -0
- package/dist/shared/excel.js +1 -0
- package/dist/shared/index.js +1 -1
- package/dist/shared/tree.js +1 -1
- package/dist/src/core/context/index.d.ts +11 -1
- package/dist/src/core/host-infra.d.ts +3 -3
- package/dist/src/routing/base.d.ts +2 -0
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/shared/excel.d.ts +13 -0
- package/dist/src/shared/index.d.ts +2 -0
- package/dist/typings/routing/crud.d.ts +2 -0
- package/package.json +3 -2
- package/src/shared/excel.d.ts +13 -0
- package/src/shared/excel.ts +46 -0
- package/src/shared/index.ts +6 -0
- package/typings/admin/comm/crud.d.ts +6 -0
- package/typings/admin/comm/crud.ts +6 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<button
|
|
3
|
+
v-if="visible"
|
|
4
|
+
type="button"
|
|
5
|
+
class="vm-crud-toolbar__btn is-ghost"
|
|
6
|
+
:disabled="disabled || submitting"
|
|
7
|
+
@click="onExport"
|
|
8
|
+
>
|
|
9
|
+
<i class="ri-download-2-line" />
|
|
10
|
+
{{ buttonText }}
|
|
11
|
+
</button>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { computed, inject, ref } from 'vue'
|
|
16
|
+
import { toast } from 'vue-sonner'
|
|
17
|
+
import {
|
|
18
|
+
exportCrudExcel,
|
|
19
|
+
flattenExportRows,
|
|
20
|
+
pickExportColumns,
|
|
21
|
+
} from '../lib/export-excel'
|
|
22
|
+
import {
|
|
23
|
+
injectTableOptions,
|
|
24
|
+
TABLE_API_KEY,
|
|
25
|
+
type TableApi,
|
|
26
|
+
} from './key'
|
|
27
|
+
import { useCrud } from './useCrud'
|
|
28
|
+
|
|
29
|
+
defineOptions({ name: 'vm-export-btn' })
|
|
30
|
+
|
|
31
|
+
const props = withDefaults(
|
|
32
|
+
defineProps<{
|
|
33
|
+
/** 列配置;默认取 Table.getColumns() 或 useTable columns */
|
|
34
|
+
columns?: CrudColumn[]
|
|
35
|
+
/** 自定义数据源;默认按当前筛选 POST page 拉全量 */
|
|
36
|
+
data?:
|
|
37
|
+
| Record<string, unknown>[]
|
|
38
|
+
| ((params: Record<string, unknown>) => Promise<Record<string, unknown>[]>)
|
|
39
|
+
filename?: string | (() => string)
|
|
40
|
+
maxExportLimit?: number
|
|
41
|
+
disabled?: boolean
|
|
42
|
+
text?: string
|
|
43
|
+
/** 权限键,默认 page */
|
|
44
|
+
permission?: keyof CrudPermission
|
|
45
|
+
}>(),
|
|
46
|
+
{
|
|
47
|
+
filename: '导出',
|
|
48
|
+
maxExportLimit: 5000,
|
|
49
|
+
disabled: false,
|
|
50
|
+
permission: 'page',
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
const crud = useCrud()
|
|
55
|
+
const tableOpts = injectTableOptions()
|
|
56
|
+
const tableApi = inject(TABLE_API_KEY, null as TableApi | null)
|
|
57
|
+
const submitting = ref(false)
|
|
58
|
+
|
|
59
|
+
const visible = computed(() => Boolean(crud.getPermission(props.permission)))
|
|
60
|
+
|
|
61
|
+
const buttonText = computed(
|
|
62
|
+
() => props.text || crud.dict.label.export || '导出',
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
const exportColumns = computed(() => {
|
|
66
|
+
const raw =
|
|
67
|
+
props.columns?.length
|
|
68
|
+
? props.columns
|
|
69
|
+
: tableApi?.getColumns() || tableOpts?.columns || []
|
|
70
|
+
return pickExportColumns(raw)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
function resolveFilename() {
|
|
74
|
+
const raw = props.filename
|
|
75
|
+
const name = typeof raw === 'function' ? raw() : raw
|
|
76
|
+
return name || '导出'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function fetchRows(): Promise<Record<string, unknown>[]> {
|
|
80
|
+
if (props.data) {
|
|
81
|
+
if (typeof props.data === 'function') {
|
|
82
|
+
return props.data({ ...crud.getParams() })
|
|
83
|
+
}
|
|
84
|
+
return props.data
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const svc = crud.service
|
|
88
|
+
const limit =
|
|
89
|
+
props.maxExportLimit && props.maxExportLimit > 0
|
|
90
|
+
? props.maxExportLimit
|
|
91
|
+
: Math.max(crud.pagination.value.total, 1)
|
|
92
|
+
|
|
93
|
+
if (svc.page) {
|
|
94
|
+
const body: Record<string, unknown> = {
|
|
95
|
+
...crud.getParams(),
|
|
96
|
+
[crud.dict.pagination.page]: 1,
|
|
97
|
+
[crud.dict.pagination.size]: limit,
|
|
98
|
+
}
|
|
99
|
+
if (crud.trashMode.value === 'onlyTrashed') body.onlyTrashed = true
|
|
100
|
+
if (crud.trashMode.value === 'withTrashed') body.withTrashed = true
|
|
101
|
+
const res = await svc.page(body)
|
|
102
|
+
return res.list || []
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (svc.list) {
|
|
106
|
+
const body: Record<string, unknown> = { ...crud.getParams() }
|
|
107
|
+
if (crud.trashMode.value === 'onlyTrashed') body.onlyTrashed = true
|
|
108
|
+
if (crud.trashMode.value === 'withTrashed') body.withTrashed = true
|
|
109
|
+
const list = await svc.list(body)
|
|
110
|
+
return Array.isArray(list) ? list : []
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return flattenExportRows(crud.list.value, tableOpts?.tree)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function onExport() {
|
|
117
|
+
if (submitting.value || props.disabled) return
|
|
118
|
+
if (!exportColumns.value.length) {
|
|
119
|
+
toast.error('没有可导出的列')
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
submitting.value = true
|
|
124
|
+
try {
|
|
125
|
+
const rows = await fetchRows()
|
|
126
|
+
if (!rows.length) {
|
|
127
|
+
toast.warning('暂无数据可导出')
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
const flat = flattenExportRows(rows, tableOpts?.tree)
|
|
131
|
+
exportCrudExcel(exportColumns.value, flat, resolveFilename())
|
|
132
|
+
toast.success('导出成功')
|
|
133
|
+
} catch (e) {
|
|
134
|
+
toast.error(e instanceof Error ? e.message : '导出失败')
|
|
135
|
+
} finally {
|
|
136
|
+
submitting.value = false
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
</script>
|
|
140
|
+
|
|
141
|
+
<style lang="scss" scoped>
|
|
142
|
+
.vm-crud-toolbar__btn {
|
|
143
|
+
display: inline-flex;
|
|
144
|
+
height: 36px;
|
|
145
|
+
align-items: center;
|
|
146
|
+
gap: 4px;
|
|
147
|
+
padding: 0 14px;
|
|
148
|
+
border: none;
|
|
149
|
+
border-radius: 12px;
|
|
150
|
+
font-size: 13px;
|
|
151
|
+
font-weight: 600;
|
|
152
|
+
cursor: pointer;
|
|
153
|
+
transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
|
|
154
|
+
|
|
155
|
+
&:disabled {
|
|
156
|
+
cursor: not-allowed;
|
|
157
|
+
opacity: 0.45;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
&.is-ghost {
|
|
161
|
+
background: var(--muted);
|
|
162
|
+
color: var(--foreground);
|
|
163
|
+
|
|
164
|
+
&:hover:not(:disabled) {
|
|
165
|
+
background: color-mix(in srgb, var(--muted) 70%, var(--foreground) 8%);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
@@ -186,14 +186,29 @@ function resolveField(item: CrudSearchItem) {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
function fieldProps(item: CrudSearchItem) {
|
|
189
|
+
const name = String(item.placeholder || item.label || '').trim()
|
|
190
|
+
const rangePlaceholders =
|
|
191
|
+
item.type === 'number-range' && name
|
|
192
|
+
? {
|
|
193
|
+
startPlaceholder: `${name}最小值`,
|
|
194
|
+
endPlaceholder: `${name}最大值`,
|
|
195
|
+
}
|
|
196
|
+
: item.type === 'daterange' && name
|
|
197
|
+
? {
|
|
198
|
+
startPlaceholder: `${name}开始`,
|
|
199
|
+
endPlaceholder: `${name}结束`,
|
|
200
|
+
}
|
|
201
|
+
: {}
|
|
189
202
|
return {
|
|
190
203
|
options: item.options,
|
|
191
204
|
placeholder: item.placeholder || item.label,
|
|
192
205
|
refreshOnChange: false,
|
|
193
206
|
precision: item.range?.rangeType,
|
|
194
|
-
mode:
|
|
195
|
-
|
|
196
|
-
|
|
207
|
+
mode:
|
|
208
|
+
item.range?.rangeType === 'float' || item.range?.rangeType === 'int'
|
|
209
|
+
? item.range.rangeType
|
|
210
|
+
: undefined,
|
|
211
|
+
...rangePlaceholders,
|
|
197
212
|
...(item.component?.props || {}),
|
|
198
213
|
}
|
|
199
214
|
}
|
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
<i class="ri-delete-bin-line" />
|
|
21
21
|
{{ deleteText || crud.dict.label.multiDelete }}
|
|
22
22
|
</button>
|
|
23
|
+
<vm-export-btn
|
|
24
|
+
v-if="showExport"
|
|
25
|
+
:text="exportText || crud.dict.label.export"
|
|
26
|
+
:filename="exportFilename"
|
|
27
|
+
:max-export-limit="maxExportLimit"
|
|
28
|
+
:columns="exportColumns"
|
|
29
|
+
:data="exportData"
|
|
30
|
+
/>
|
|
23
31
|
<slot />
|
|
24
32
|
</div>
|
|
25
33
|
<div class="vm-crud-toolbar__right">
|
|
@@ -57,6 +65,7 @@
|
|
|
57
65
|
<script setup lang="ts">
|
|
58
66
|
import { computed } from 'vue'
|
|
59
67
|
import { useCrud } from './useCrud'
|
|
68
|
+
import VmExportBtn from './vm-export-btn.vue'
|
|
60
69
|
defineOptions({ name: 'vm-toolbar' })
|
|
61
70
|
|
|
62
71
|
const props = withDefaults(
|
|
@@ -66,21 +75,32 @@ const props = withDefaults(
|
|
|
66
75
|
search?: boolean
|
|
67
76
|
showAdd?: boolean
|
|
68
77
|
showDelete?: boolean
|
|
78
|
+
/** 显示导出(默认开;需 page/list 权限) */
|
|
79
|
+
showExport?: boolean
|
|
69
80
|
/** 打开新增表单时的默认值 */
|
|
70
81
|
addData?: Record<string, unknown> | (() => Record<string, unknown>)
|
|
71
82
|
/** 回收站中是否隐藏新增(默认 true) */
|
|
72
83
|
hideAddInTrash?: boolean
|
|
73
84
|
addText?: string
|
|
74
85
|
deleteText?: string
|
|
86
|
+
exportText?: string
|
|
87
|
+
exportFilename?: string | (() => string)
|
|
88
|
+
maxExportLimit?: number
|
|
89
|
+
exportColumns?: CrudColumn[]
|
|
90
|
+
exportData?:
|
|
91
|
+
| Record<string, unknown>[]
|
|
92
|
+
| ((params: Record<string, unknown>) => Promise<Record<string, unknown>[]>)
|
|
75
93
|
}>(),
|
|
76
94
|
{
|
|
77
95
|
trash: true,
|
|
78
96
|
search: true,
|
|
79
97
|
showAdd: true,
|
|
80
98
|
showDelete: true,
|
|
99
|
+
showExport: true,
|
|
81
100
|
hideAddInTrash: true,
|
|
82
101
|
addText: '新增',
|
|
83
102
|
deleteText: '删除',
|
|
103
|
+
maxExportLimit: 5000,
|
|
84
104
|
},
|
|
85
105
|
)
|
|
86
106
|
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Dialog
|
|
3
3
|
:open="crud.upsertVisible.value"
|
|
4
|
-
@update:open="(v) => (!v ?
|
|
4
|
+
@update:open="(v) => (!v ? onCloseClick() : undefined)"
|
|
5
5
|
>
|
|
6
6
|
<DialogContent
|
|
7
7
|
shell="crud"
|
|
8
8
|
class="vm-crud-upsert"
|
|
9
|
-
:class="{
|
|
9
|
+
:class="{
|
|
10
|
+
'is-empty': isBodyEmpty,
|
|
11
|
+
'is-height': !!heightCss,
|
|
12
|
+
}"
|
|
13
|
+
:style="heightCss ? { '--vm-dialog-height': heightCss } : undefined"
|
|
10
14
|
@pointer-down-outside="onPointerDownOutside"
|
|
11
15
|
@focus-outside="onFocusOutside"
|
|
12
16
|
@interact-outside="onInteractOutside"
|
|
@@ -14,7 +18,10 @@
|
|
|
14
18
|
<DialogHeader class="vm-crud-upsert__head">
|
|
15
19
|
<DialogTitle class="vm-crud-upsert__title">{{ titleText }}</DialogTitle>
|
|
16
20
|
</DialogHeader>
|
|
17
|
-
<div
|
|
21
|
+
<div
|
|
22
|
+
class="vm-crud-upsert__body"
|
|
23
|
+
:class="{ 'is-fill': layout === 'fill' }"
|
|
24
|
+
>
|
|
18
25
|
<template v-if="!isBodyEmpty">
|
|
19
26
|
<div
|
|
20
27
|
v-for="item in formItemsBeforeSlot"
|
|
@@ -33,7 +40,7 @@
|
|
|
33
40
|
:name="`upsert-${item.prop}`"
|
|
34
41
|
:options="resolveOptions(item.options)"
|
|
35
42
|
:model-value="String(crud.upsertForm.value[item.prop] ?? '')"
|
|
36
|
-
:disabled="isInfo"
|
|
43
|
+
:disabled="isInfo || item.disabled"
|
|
37
44
|
@update:model-value="(v) => setField(item.prop, v)"
|
|
38
45
|
/>
|
|
39
46
|
|
|
@@ -43,7 +50,7 @@
|
|
|
43
50
|
:class="fieldClass(item)"
|
|
44
51
|
v-bind="fieldProps(item)"
|
|
45
52
|
:model-value="crud.upsertForm.value[item.prop]"
|
|
46
|
-
:disabled="isInfo"
|
|
53
|
+
:disabled="isInfo || item.disabled"
|
|
47
54
|
@update:model-value="(v: unknown) => setField(item.prop, v)"
|
|
48
55
|
/>
|
|
49
56
|
|
|
@@ -51,7 +58,7 @@
|
|
|
51
58
|
v-else
|
|
52
59
|
class="vm-crud-upsert__control"
|
|
53
60
|
:placeholder="item.placeholder"
|
|
54
|
-
:disabled="isInfo"
|
|
61
|
+
:disabled="isInfo || item.disabled"
|
|
55
62
|
:aria-invalid="fieldErrors[item.prop] ? true : undefined"
|
|
56
63
|
:model-value="String(crud.upsertForm.value[item.prop] ?? '')"
|
|
57
64
|
@update:model-value="(v) => setField(item.prop, v)"
|
|
@@ -76,7 +83,7 @@
|
|
|
76
83
|
<textarea
|
|
77
84
|
class="vm-crud-upsert__textarea"
|
|
78
85
|
:placeholder="item.placeholder"
|
|
79
|
-
:disabled="isInfo"
|
|
86
|
+
:disabled="isInfo || item.disabled"
|
|
80
87
|
:value="String(crud.upsertForm.value[item.prop] ?? '')"
|
|
81
88
|
@input="setField(item.prop, ($event.target as HTMLTextAreaElement).value)"
|
|
82
89
|
/>
|
|
@@ -89,24 +96,34 @@
|
|
|
89
96
|
<vm-empty kind="暂无内容" />
|
|
90
97
|
</div>
|
|
91
98
|
</div>
|
|
92
|
-
<DialogFooter class="vm-crud-upsert__foot">
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
99
|
+
<DialogFooter v-if="showFooter" class="vm-crud-upsert__foot">
|
|
100
|
+
<slot
|
|
101
|
+
v-if="slots.footer"
|
|
102
|
+
name="footer"
|
|
103
|
+
v-bind="footerSlotProps"
|
|
104
|
+
/>
|
|
105
|
+
<template v-else>
|
|
106
|
+
<slot name="footer-prepend" v-bind="footerSlotProps" />
|
|
107
|
+
<button
|
|
108
|
+
v-if="showClose"
|
|
109
|
+
type="button"
|
|
110
|
+
class="vm-crud-upsert__btn is-ghost"
|
|
111
|
+
:disabled="submitting"
|
|
112
|
+
@click="onCloseClick"
|
|
113
|
+
>
|
|
114
|
+
{{ closeLabel }}
|
|
115
|
+
</button>
|
|
116
|
+
<button
|
|
117
|
+
v-if="showConfirm"
|
|
118
|
+
type="button"
|
|
119
|
+
class="vm-crud-upsert__btn is-primary"
|
|
120
|
+
:disabled="submitting"
|
|
121
|
+
@click="onConfirmClick"
|
|
122
|
+
>
|
|
123
|
+
{{ submitting ? '提交中…' : confirmLabel }}
|
|
124
|
+
</button>
|
|
125
|
+
<slot name="footer-append" v-bind="footerSlotProps" />
|
|
126
|
+
</template>
|
|
110
127
|
</DialogFooter>
|
|
111
128
|
</DialogContent>
|
|
112
129
|
</Dialog>
|
|
@@ -128,10 +145,32 @@ const props = withDefaults(
|
|
|
128
145
|
defineProps<{
|
|
129
146
|
items?: CrudFormItem[]
|
|
130
147
|
title?: string
|
|
148
|
+
/** 弹窗高度,如 800 / '800px';最高受壳层 800px 约束 */
|
|
149
|
+
height?: string | number
|
|
150
|
+
/** 是否显示确定;未设时 info 模式自动隐藏 */
|
|
151
|
+
confirm?: boolean
|
|
152
|
+
/** 是否显示关闭,默认 true */
|
|
153
|
+
close?: boolean
|
|
154
|
+
/** false 时隐藏整个底栏 */
|
|
155
|
+
footer?: boolean
|
|
156
|
+
confirmText?: string
|
|
157
|
+
closeText?: string
|
|
158
|
+
/** form=栅格表单;fill=纵向铺满(只读列表/文档) */
|
|
159
|
+
layout?: 'form' | 'fill'
|
|
131
160
|
}>(),
|
|
132
|
-
{
|
|
161
|
+
{
|
|
162
|
+
close: undefined,
|
|
163
|
+
confirm: undefined,
|
|
164
|
+
footer: true,
|
|
165
|
+
layout: 'form',
|
|
166
|
+
},
|
|
133
167
|
)
|
|
134
168
|
|
|
169
|
+
const emit = defineEmits<{
|
|
170
|
+
close: []
|
|
171
|
+
confirm: []
|
|
172
|
+
}>()
|
|
173
|
+
|
|
135
174
|
const slots = useSlots()
|
|
136
175
|
const crud = useCrud()
|
|
137
176
|
const upsertOpts = injectUpsertOptions()
|
|
@@ -139,6 +178,16 @@ const formCols = useFormCols()
|
|
|
139
178
|
const submitting = ref(false)
|
|
140
179
|
const fieldErrors = ref<Record<string, string>>({})
|
|
141
180
|
|
|
181
|
+
function normalizeHeight(h?: string | number) {
|
|
182
|
+
if (h == null || h === '') return ''
|
|
183
|
+
if (typeof h === 'number') return `${h}px`
|
|
184
|
+
return String(h)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const heightCss = computed(() =>
|
|
188
|
+
normalizeHeight(props.height ?? upsertOpts?.dialog?.height),
|
|
189
|
+
)
|
|
190
|
+
|
|
142
191
|
const mergedItems = computed(() => {
|
|
143
192
|
const raw = props.items?.length ? props.items : upsertOpts?.items || []
|
|
144
193
|
const useRules = getCrudStyle().form.plugins.some(
|
|
@@ -171,16 +220,46 @@ const formItemsAfterSlot = computed(() =>
|
|
|
171
220
|
)
|
|
172
221
|
|
|
173
222
|
const isInfo = computed(() => crud.upsertMode.value === 'info')
|
|
174
|
-
/** dialog.confirm
|
|
223
|
+
/** prop > dialog.confirm > info 自动隐藏 */
|
|
175
224
|
const showConfirm = computed(() => {
|
|
225
|
+
if (typeof props.confirm === 'boolean') return props.confirm
|
|
176
226
|
const flag = upsertOpts?.dialog?.confirm
|
|
177
227
|
if (typeof flag === 'boolean') return flag
|
|
178
228
|
return !isInfo.value
|
|
179
229
|
})
|
|
230
|
+
const showClose = computed(() => {
|
|
231
|
+
if (typeof props.close === 'boolean') return props.close
|
|
232
|
+
const flag = upsertOpts?.dialog?.close
|
|
233
|
+
if (typeof flag === 'boolean') return flag
|
|
234
|
+
return true
|
|
235
|
+
})
|
|
236
|
+
const showFooter = computed(() => props.footer !== false)
|
|
237
|
+
const confirmLabel = computed(
|
|
238
|
+
() =>
|
|
239
|
+
props.confirmText ||
|
|
240
|
+
upsertOpts?.dialog?.confirmText ||
|
|
241
|
+
crud.dict.label.confirm,
|
|
242
|
+
)
|
|
243
|
+
const closeLabel = computed(
|
|
244
|
+
() =>
|
|
245
|
+
props.closeText ||
|
|
246
|
+
upsertOpts?.dialog?.closeText ||
|
|
247
|
+
crud.dict.label.close,
|
|
248
|
+
)
|
|
180
249
|
const isBodyEmpty = computed(
|
|
181
250
|
() => !visibleItems.value.length && !slots.default,
|
|
182
251
|
)
|
|
183
252
|
|
|
253
|
+
const footerSlotProps = computed(() => ({
|
|
254
|
+
close: onCloseClick,
|
|
255
|
+
submit: onSubmit,
|
|
256
|
+
confirm: onConfirmClick,
|
|
257
|
+
submitting: submitting.value,
|
|
258
|
+
showConfirm: showConfirm.value,
|
|
259
|
+
showClose: showClose.value,
|
|
260
|
+
form: crud.upsertForm.value,
|
|
261
|
+
}))
|
|
262
|
+
|
|
184
263
|
function onPointerDownOutside(event: Event) {
|
|
185
264
|
if (isDialogFloatTarget(event)) event.preventDefault()
|
|
186
265
|
}
|
|
@@ -263,9 +342,25 @@ function itemSpan(item: CrudFormItem) {
|
|
|
263
342
|
return resolveFormSpan(item.span, formCols.value)
|
|
264
343
|
}
|
|
265
344
|
|
|
345
|
+
function onCloseClick() {
|
|
346
|
+
const done = () => crud.upsertClose()
|
|
347
|
+
if (upsertOpts?.onClose) {
|
|
348
|
+
upsertOpts.onClose('close', done)
|
|
349
|
+
emit('close')
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
done()
|
|
353
|
+
emit('close')
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function onConfirmClick() {
|
|
357
|
+
emit('confirm')
|
|
358
|
+
void onSubmit()
|
|
359
|
+
}
|
|
360
|
+
|
|
266
361
|
async function onSubmit() {
|
|
267
362
|
if (isInfo.value) {
|
|
268
|
-
|
|
363
|
+
onCloseClick()
|
|
269
364
|
return
|
|
270
365
|
}
|
|
271
366
|
if (submitting.value) return
|
|
@@ -345,7 +440,7 @@ defineExpose({
|
|
|
345
440
|
form: crud.upsertForm,
|
|
346
441
|
mode: crud.upsertMode,
|
|
347
442
|
submit: onSubmit,
|
|
348
|
-
close:
|
|
443
|
+
close: onCloseClick,
|
|
349
444
|
add: () => crud.rowAdd(),
|
|
350
445
|
append: (data?: Record<string, unknown>) => crud.rowAppend(data),
|
|
351
446
|
edit: (data: Record<string, unknown>) => crud.rowEdit(data),
|
|
@@ -382,6 +477,19 @@ defineExpose({
|
|
|
382
477
|
padding: 18px 22px;
|
|
383
478
|
align-content: start;
|
|
384
479
|
|
|
480
|
+
&.is-fill {
|
|
481
|
+
display: flex;
|
|
482
|
+
flex-direction: column;
|
|
483
|
+
align-items: stretch;
|
|
484
|
+
gap: 0;
|
|
485
|
+
padding: 0;
|
|
486
|
+
|
|
487
|
+
> * {
|
|
488
|
+
width: 100%;
|
|
489
|
+
min-width: 0;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
385
493
|
/* slot 内容在宿主 SFC,须 :deep 才能命中 label / control 样式 */
|
|
386
494
|
:deep(.vm-crud-upsert__field) {
|
|
387
495
|
display: grid;
|
|
@@ -408,6 +516,25 @@ defineExpose({
|
|
|
408
516
|
line-height: 1.4 !important;
|
|
409
517
|
}
|
|
410
518
|
|
|
519
|
+
/* 单行 input:白底;select / tree-select 等:淡蓝底 */
|
|
520
|
+
:deep(input.vm-crud-upsert__control),
|
|
521
|
+
:deep(.vm-crud-upsert__control[data-slot='input']) {
|
|
522
|
+
background: var(--card) !important;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
:deep(.vm-crud-select.vm-crud-upsert__control),
|
|
526
|
+
:deep(.vm-group-cascader.vm-crud-upsert__control),
|
|
527
|
+
:deep(.vm-multi-select.vm-crud-upsert__control),
|
|
528
|
+
:deep(.vm-user-select.vm-crud-upsert__control),
|
|
529
|
+
:deep(.vm-date-picker.vm-crud-upsert__control),
|
|
530
|
+
:deep(.vm-icon-picker.vm-crud-upsert__control) {
|
|
531
|
+
background: var(--muted) !important;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
:deep(.vm-tree-select.vm-crud-upsert__control .vm-tree-select__trigger) {
|
|
535
|
+
background: var(--muted) !important;
|
|
536
|
+
}
|
|
537
|
+
|
|
411
538
|
@media (max-width: 768px) {
|
|
412
539
|
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
413
540
|
flex: 1 1 auto;
|
|
@@ -443,11 +570,12 @@ defineExpose({
|
|
|
443
570
|
min-height: var(--vm-control-height);
|
|
444
571
|
}
|
|
445
572
|
|
|
446
|
-
/* 上传:按 size
|
|
573
|
+
/* 上传:按 size 撑开,勿套用单行输入框高度;淡蓝底 */
|
|
447
574
|
:deep(.vm-upload.vm-crud-upsert__upload-field) {
|
|
448
575
|
width: 100%;
|
|
449
576
|
height: auto !important;
|
|
450
577
|
min-height: 0;
|
|
578
|
+
background: var(--muted) !important;
|
|
451
579
|
}
|
|
452
580
|
|
|
453
581
|
:deep(.vm-crud-upsert__switch-field.vm-switch) {
|
|
@@ -456,13 +584,14 @@ defineExpose({
|
|
|
456
584
|
margin-top: 8px;
|
|
457
585
|
}
|
|
458
586
|
|
|
459
|
-
.vm-crud-upsert__textarea
|
|
587
|
+
.vm-crud-upsert__textarea,
|
|
588
|
+
:deep(.vm-crud-upsert__textarea) {
|
|
460
589
|
width: 100%;
|
|
461
590
|
min-height: 72px;
|
|
462
591
|
padding: 8px var(--vm-control-padding-x);
|
|
463
592
|
border: 1px solid var(--input);
|
|
464
593
|
border-radius: var(--vm-control-radius);
|
|
465
|
-
background: var(--
|
|
594
|
+
background: var(--muted);
|
|
466
595
|
color: var(--foreground);
|
|
467
596
|
font-size: 14px;
|
|
468
597
|
line-height: 1.5;
|
|
@@ -496,7 +625,8 @@ defineExpose({
|
|
|
496
625
|
}
|
|
497
626
|
}
|
|
498
627
|
|
|
499
|
-
.vm-crud-upsert__btn
|
|
628
|
+
.vm-crud-upsert__btn,
|
|
629
|
+
:slotted(.vm-crud-upsert__btn) {
|
|
500
630
|
height: 36px;
|
|
501
631
|
padding: 0 16px;
|
|
502
632
|
border: none;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
function _0x622a(_0x3ab13a,_0x441a97){_0x3ab13a=_0x3ab13a-0x18c;const _0xaa6562=_0xaa65();let _0x622ad4=_0xaa6562[_0x3ab13a];if(_0x622a['osojKD']===undefined){var _0xd8df14=function(_0x28d264){const _0x99e36a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1c9e9c='',_0x3a3ea5='';for(let _0x3f0e96=0x0,_0x59bd40,_0x1378ab,_0x242ac0=0x0;_0x1378ab=_0x28d264['charAt'](_0x242ac0++);~_0x1378ab&&(_0x59bd40=_0x3f0e96%0x4?_0x59bd40*0x40+_0x1378ab:_0x1378ab,_0x3f0e96++%0x4)?_0x1c9e9c+=String['fromCharCode'](0xff&_0x59bd40>>(-0x2*_0x3f0e96&0x6)):0x0){_0x1378ab=_0x99e36a['indexOf'](_0x1378ab);}for(let _0x50d856=0x0,_0x2ef7e6=_0x1c9e9c['length'];_0x50d856<_0x2ef7e6;_0x50d856++){_0x3a3ea5+='%'+('00'+_0x1c9e9c['charCodeAt'](_0x50d856)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3a3ea5);};_0x622a['bRkgta']=_0xd8df14,_0x622a['CcUuPJ']={},_0x622a['osojKD']=!![];}const _0x494071=_0xaa6562[0x0],_0x22a695=_0x3ab13a+_0x494071,_0x2b562b=_0x622a['CcUuPJ'][_0x22a695];return!_0x2b562b?(_0x622ad4=_0x622a['bRkgta'](_0x622ad4),_0x622a['CcUuPJ'][_0x22a695]=_0x622ad4):_0x622ad4=_0x2b562b,_0x622ad4;}(function(_0x36c97a,_0x3a20e0){const _0x5baba2=_0x622a,_0x36835a=_0x36c97a();while(!![]){try{const _0x201fee=-parseInt(_0x5baba2(0x192))/0x1*(parseInt(_0x5baba2(0x194))/0x2)+parseInt(_0x5baba2(0x195))/0x3+parseInt(_0x5baba2(0x18d))/0x4*(-parseInt(_0x5baba2(0x190))/0x5)+parseInt(_0x5baba2(0x197))/0x6*(-parseInt(_0x5baba2(0x198))/0x7)+parseInt(_0x5baba2(0x196))/0x8+-parseInt(_0x5baba2(0x18c))/0x9+-parseInt(_0x5baba2(0x191))/0xa*(-parseInt(_0x5baba2(0x18e))/0xb);if(_0x201fee===_0x3a20e0)break;else _0x36835a['push'](_0x36835a['shift']());}catch(_0x5b410a){_0x36835a['push'](_0x36835a['shift']());}}}(_0xaa65,0xdbc7e));import{useUserStore}from'../stores/user';export const vPerm={'mounted'(_0x1c9e9c,_0x3a3ea5){const _0x16e233=_0x622a;apply(_0x1c9e9c,_0x3a3ea5[_0x16e233(0x18f)]);},'updated'(_0x3f0e96,_0x59bd40){const _0x4421=_0x622a;apply(_0x3f0e96,_0x59bd40[_0x4421(0x18f)]);}};function _0xaa65(){const _0x1e61ad=['mJq4oduXmMfXAxr3tW','mte2mduZmtj6ENzxtNK','nJztufzMC1G','ndi2nJqZBML0AK1Q','BM9Uzq','AgfZugvYBq','mJm5nZi4nwXxvhbdyG','nhn5yKnOEa','mJe0nJfmuLngz0m','DMfSDwu','nZyXnJG0nuDXrfjACq','mtqWmtbMv3LksgK','nZuXndjRCK5Vv20','zgLZCgXHEq','ndrNrhncsK0'];_0xaa65=function(){return _0x1e61ad;};return _0xaa65();}function apply(_0x1378ab,_0x242ac0){const _0x4ea219=_0x622a,_0x50d856=useUserStore(),_0x2ef7e6=_0x50d856[_0x4ea219(0x19a)](_0x242ac0);_0x1378ab['style'][_0x4ea219(0x193)]=_0x2ef7e6?'':_0x4ea219(0x199);}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _0xec4011=_0x1634;(function(_0xfcf429,_0x3412e5){const _0x4bfa20=_0x1634,_0x120349=_0xfcf429();while(!![]){try{const _0x3ec625=parseInt(_0x4bfa20(0x100))/0x1+parseInt(_0x4bfa20(0xf2))/0x2+-parseInt(_0x4bfa20(0xf5))/0x3+-parseInt(_0x4bfa20(0xfd))/0x4+-parseInt(_0x4bfa20(0x103))/0x5*(-parseInt(_0x4bfa20(0xff))/0x6)+-parseInt(_0x4bfa20(0xf3))/0x7+parseInt(_0x4bfa20(0x104))/0x8*(parseInt(_0x4bfa20(0xf0))/0x9);if(_0x3ec625===_0x3412e5)break;else _0x120349['push'](_0x120349['shift']());}catch(_0x51c921){_0x120349['push'](_0x120349['shift']());}}}(_0x3671,0x1f5ec));import{toast}from'vue-sonner';import{request}from'../api/client';import{extname,filename,pathJoin,uploadUid}from'../lib/upload';function _0x3671(){const _0xe7fe12=['BwLU','A2v5','DxjS','C2XPy2u','zxjYB3i','5lIk5lYG5zYW5z2a5PEG5Pwi','B25LCNjVCG','DxbSB2fK','zMLSzq','mti4ndi5mxbfCKPREa','zw50CMLLCW','ode3mdHHDxv1wxO','mtC5mty1ruTPD2PJ','Bg9HzgvK','mZqYndq0CLHnCfb6','zMXVB3i','BMfTzq','BgvUz3rOq29TChv0ywjSzq','yxbWl2jHC2u','C3rYAw5NAwz5','5lIk5lYG5AsX6lsLicG','B25SB2fK','nZm5mJy0CM12yvzZ','yxbWzw5K','ntG2mMLczLnWCG','ndG2otzTzevgqwm','Dg90ywW','B25WCM9NCMvZCW','mteZmg5VBM5NAG','ofPAt2fVEG','Ag9ZDa','C3rHDhvZ','B3bLBG','5lIk5lYG572r57UC6zsz6k+V','ChjLDMLLDW','CMvZCg9UC2vuzxH0','DxbSB2fKvxjS','l2fKBwLUl2jHC2uVy29TBs91CgXVywq','C2vUza','AgfZ'];_0x3671=function(){return _0xe7fe12;};return _0x3671();}const UPLOAD_PATH=_0xec4011(0x10c),SIGN_SKIP=new Set([_0xec4011(0x111),_0xec4011(0x105),_0xec4011(0x10b),'publicDomain','previewUrl',_0xec4011(0x109)]);function _0x1634(_0x29af9c,_0x59986f){_0x29af9c=_0x29af9c-0xec;const _0x3671d5=_0x3671();let _0x163470=_0x3671d5[_0x29af9c];if(_0x1634['lcWGkf']===undefined){var _0x4f040e=function(_0x351c57){const _0x174e1f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x39a2ed='',_0x404779='';for(let _0x3160ef=0x0,_0x59856a,_0x80bb7f,_0x12d4fa=0x0;_0x80bb7f=_0x351c57['charAt'](_0x12d4fa++);~_0x80bb7f&&(_0x59856a=_0x3160ef%0x4?_0x59856a*0x40+_0x80bb7f:_0x80bb7f,_0x3160ef++%0x4)?_0x39a2ed+=String['fromCharCode'](0xff&_0x59856a>>(-0x2*_0x3160ef&0x6)):0x0){_0x80bb7f=_0x174e1f['indexOf'](_0x80bb7f);}for(let _0x15bc5f=0x0,_0x5208a0=_0x39a2ed['length'];_0x15bc5f<_0x5208a0;_0x15bc5f++){_0x404779+='%'+('00'+_0x39a2ed['charCodeAt'](_0x15bc5f)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x404779);};_0x1634['MSgFmn']=_0x4f040e,_0x1634['VyreKC']={},_0x1634['lcWGkf']=!![];}const _0x26d324=_0x3671d5[0x0],_0xb2f64=_0x29af9c+_0x26d324,_0x10aac7=_0x1634['VyreKC'][_0xb2f64];return!_0x10aac7?(_0x163470=_0x1634['MSgFmn'](_0x163470),_0x1634['VyreKC'][_0xb2f64]=_0x163470):_0x163470=_0x10aac7,_0x163470;}export function useUpload(){async function _0x39a2ed(_0x404779,_0x3160ef={}){const _0x40df3f=_0x1634,{prefixPath:prefixPath=_0x40df3f(0xf9),onProgress:_0x59856a}=_0x3160ef,_0x80bb7f=uploadUid(),_0x12d4fa=extname(_0x404779['name']),_0x15bc5f=filename(_0x404779[_0x40df3f(0xf7)])+'_'+_0x80bb7f+(_0x12d4fa?'.'+_0x12d4fa:''),_0x5208a0=pathJoin(prefixPath,_0x15bc5f),_0x56395b=await request(UPLOAD_PATH,{'method':'POST','body':JSON[_0x40df3f(0xfa)]({})}),_0x39b020=String(_0x56395b[_0x40df3f(0x105)]||_0x56395b[_0x40df3f(0x111)]||_0x56395b['uploadUrl']||'');if(!_0x39b020)throw new Error(_0x40df3f(0xec));const _0x2f6847=new FormData();_0x2f6847['append'](_0x40df3f(0x110),_0x5208a0);for(const [_0x3481d4,_0x2ffb67]of Object[_0x40df3f(0xf1)](_0x56395b)){if(SIGN_SKIP[_0x40df3f(0x10e)](_0x3481d4)||_0x2ffb67==null||_0x2f6847[_0x40df3f(0x10e)](_0x3481d4))continue;_0x2f6847[_0x40df3f(0xfe)](_0x3481d4,String(_0x2ffb67));}_0x2f6847[_0x40df3f(0xfe)](_0x40df3f(0xef),_0x404779),await xhrUpload(_0x39b020,_0x2f6847,_0x59856a);const _0x408c9f=String(_0x56395b['publicDomain']||_0x56395b['previewUrl']||_0x39b020);return{'url':pathJoin(_0x408c9f,_0x5208a0),'key':_0x5208a0,'fileId':_0x80bb7f};}return{'toUpload':_0x39a2ed};}function xhrUpload(_0xa04e48,_0x2effa8,_0x128040){return new Promise((_0x57de9d,_0x2a782e)=>{const _0x37d82c=_0x1634,_0x44e20e=new XMLHttpRequest();_0x44e20e[_0x37d82c(0x107)]('POST',_0xa04e48),_0x44e20e[_0x37d82c(0xee)][_0x37d82c(0x102)]=_0x1490fd=>{const _0x281b14=_0x37d82c;if(!_0x1490fd[_0x281b14(0xf8)])return;_0x128040?.(Math[_0x281b14(0x10f)](0x64,Math[_0x281b14(0xf6)](_0x1490fd[_0x281b14(0xf4)]/_0x1490fd[_0x281b14(0x101)]*0x64)));},_0x44e20e[_0x37d82c(0xfc)]=()=>{const _0xced8bb=_0x37d82c;if(_0x44e20e[_0xced8bb(0x106)]<0xc8||_0x44e20e['status']>=0x12c){const _0x26bc68=_0x44e20e[_0xced8bb(0x10a)]||_0xced8bb(0xfb)+_0x44e20e[_0xced8bb(0x106)]+')';toast[_0xced8bb(0x113)](_0x26bc68[_0xced8bb(0x112)](0x0,0xc8)),_0x2a782e(new Error(_0x26bc68));return;}_0x128040?.(0x64),_0x57de9d();},_0x44e20e[_0x37d82c(0xed)]=()=>_0x2a782e(new Error(_0x37d82c(0x108))),_0x44e20e[_0x37d82c(0x10d)](_0x2effa8);});}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
function _0x242c(_0x25100e,_0x544b11){_0x25100e=_0x25100e-0x131;const _0x4e3f3a=_0x4e3f();let _0x242cb9=_0x4e3f3a[_0x25100e];if(_0x242c['NcpGTy']===undefined){var _0x603da4=function(_0x22d50d){const _0x208ee2='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x37e7fd='',_0x33e2f0='';for(let _0x39d077=0x0,_0x2a5b36,_0x3be13f,_0x344f35=0x0;_0x3be13f=_0x22d50d['charAt'](_0x344f35++);~_0x3be13f&&(_0x2a5b36=_0x39d077%0x4?_0x2a5b36*0x40+_0x3be13f:_0x3be13f,_0x39d077++%0x4)?_0x37e7fd+=String['fromCharCode'](0xff&_0x2a5b36>>(-0x2*_0x39d077&0x6)):0x0){_0x3be13f=_0x208ee2['indexOf'](_0x3be13f);}for(let _0x4c7a94=0x0,_0x323177=_0x37e7fd['length'];_0x4c7a94<_0x323177;_0x4c7a94++){_0x33e2f0+='%'+('00'+_0x37e7fd['charCodeAt'](_0x4c7a94)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x33e2f0);};_0x242c['KDwKHM']=_0x603da4,_0x242c['zstYep']={},_0x242c['NcpGTy']=!![];}const _0x59207e=_0x4e3f3a[0x0],_0x1f388f=_0x25100e+_0x59207e,_0x2cd8b9=_0x242c['zstYep'][_0x1f388f];return!_0x2cd8b9?(_0x242cb9=_0x242c['KDwKHM'](_0x242cb9),_0x242c['zstYep'][_0x1f388f]=_0x242cb9):_0x242cb9=_0x2cd8b9,_0x242cb9;}(function(_0xd16cd0,_0xb28621){const _0x562ac2=_0x242c,_0x427bb2=_0xd16cd0();while(!![]){try{const _0x517421=parseInt(_0x562ac2(0x133))/0x1*(parseInt(_0x562ac2(0x13a))/0x2)+-parseInt(_0x562ac2(0x13e))/0x3*(parseInt(_0x562ac2(0x140))/0x4)+parseInt(_0x562ac2(0x13b))/0x5+-parseInt(_0x562ac2(0x131))/0x6*(parseInt(_0x562ac2(0x13c))/0x7)+-parseInt(_0x562ac2(0x139))/0x8+-parseInt(_0x562ac2(0x138))/0x9*(parseInt(_0x562ac2(0x135))/0xa)+parseInt(_0x562ac2(0x137))/0xb*(parseInt(_0x562ac2(0x13d))/0xc);if(_0x517421===_0xb28621)break;else _0x427bb2['push'](_0x427bb2['shift']());}catch(_0x43312b){_0x427bb2['push'](_0x427bb2['shift']());}}}(_0x4e3f,0xc89df));export function getBrowser(){const _0x30f155=_0x242c,{clientHeight:_0x37e7fd,clientWidth:_0x33e2f0}=document[_0x30f155(0x141)],_0x39d077=navigator[_0x30f155(0x13f)][_0x30f155(0x136)]();let _0x2a5b36=(_0x39d077[_0x30f155(0x132)](/firefox|chrome|safari|opera/g)||['other'])[0x0];if((_0x39d077['match'](/msie|trident/g)||[])[0x0])_0x2a5b36='msie';let _0x3be13f=_0x30f155(0x134);if(_0x33e2f0<0x300)_0x3be13f='xs';else{if(_0x33e2f0<0x3e0)_0x3be13f='sm';else{if(_0x33e2f0<0x4b0)_0x3be13f='md';else{if(_0x33e2f0<0x780)_0x3be13f='xl';}}}const _0x344f35=!/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i[_0x30f155(0x142)](_0x39d077);return{'height':_0x37e7fd,'width':_0x33e2f0,'type':_0x2a5b36,'screen':_0x3be13f,'isMini':_0x3be13f==='xs'||!_0x344f35};}function _0x4e3f(){const _0x1ac6bc=['mti1mteYvLvwDhfu','zg9JDw1LBNrfBgvTzw50','DgvZDa','mte0sMfdDK9Y','Bwf0y2G','ndmXnJHbq2vIELm','zNvSBa','mZmWCwfuEePn','Dg9mB3DLCKnHC2u','ndGXmJe1ouDfDerXCG','mta3nduXqMLus1nv','ntm1nJm3nLP2uLfkAq','ngDrq3bVCq','ode1mJaXmgXKD3LSqG','mteWnduZAhfSDLfk','mJrtqvrSvLq','mZLnsLD0B0C','DxnLCKfNzw50'];_0x4e3f=function(){return _0x1ac6bc;};return _0x4e3f();}
|