@xuekl/cli-components 1.6.1 → 1.8.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/PageContainer.vue +67 -32
- package/XklButton.vue +37 -6
- package/XklDropdownItem.vue +27 -0
- package/XklForm.vue +13 -18
- package/XklFormInfo.vue +8 -1
- package/XklSelect.vue +15 -5
- package/XklTable.vue +2 -1
- package/XklUpload.vue +2 -1
- package/package.json +2 -2
package/PageContainer.vue
CHANGED
|
@@ -1,57 +1,92 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="page-container">
|
|
3
|
-
<div v-if="queryVisible" class="page-query" :class="['mb-' + gutters]">
|
|
3
|
+
<div v-if="queryVisible" class="page-query part-bg" :class="['mb-' + gutters, 'pd-' + padding]">
|
|
4
4
|
<slot name="query"></slot>
|
|
5
5
|
</div>
|
|
6
|
-
<div class="page-
|
|
6
|
+
<div v-for="upper in upperSlots" :key="upper" class="page-upper part-bg"
|
|
7
|
+
:class="['mb-' + gutters, 'pd-' + padding]">
|
|
8
|
+
<slot :name="upper"></slot>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="page-body part-bg" :class="['pd-' + padding]">
|
|
7
11
|
<slot></slot>
|
|
8
12
|
</div>
|
|
9
|
-
<div v-
|
|
13
|
+
<div v-for="down in downSlots" class="page-down part-bg" :class="['mt-' + gutters, 'pd-' + padding]">
|
|
14
|
+
<slot :name="down"></slot>
|
|
15
|
+
</div>
|
|
16
|
+
<div v-if="footerVisible" class="page-footer part-bg"
|
|
17
|
+
:class="['mt-' + gutters, 'pd-' + padding, { 'footer-fixed': footerFixed }]">
|
|
10
18
|
<slot name="footer"></slot>
|
|
11
19
|
</div>
|
|
20
|
+
<div v-if="footerFixed" :style="{ height: footerHeight + 'px' }"></div>
|
|
12
21
|
</div>
|
|
13
22
|
</template>
|
|
14
23
|
<script lang="ts">
|
|
15
|
-
|
|
24
|
+
export default {
|
|
25
|
+
name: 'PageContainer'
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
<script lang="ts" setup>
|
|
29
|
+
import { onMounted, ref } from 'vue'
|
|
30
|
+
const props = defineProps({
|
|
31
|
+
gutters: {
|
|
32
|
+
type: Number,
|
|
33
|
+
default: 2
|
|
34
|
+
},
|
|
35
|
+
queryVisible: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
default: true
|
|
38
|
+
},
|
|
39
|
+
footerVisible: {
|
|
40
|
+
type: Boolean,
|
|
41
|
+
default: true
|
|
42
|
+
},
|
|
43
|
+
footerFixed: {
|
|
44
|
+
type: Boolean
|
|
45
|
+
},
|
|
46
|
+
upperSlots: {
|
|
47
|
+
type: Array,
|
|
48
|
+
default: []
|
|
49
|
+
},
|
|
50
|
+
downSlots: {
|
|
51
|
+
type: Array,
|
|
52
|
+
default: []
|
|
53
|
+
},
|
|
54
|
+
padding: {
|
|
55
|
+
type: Number,
|
|
56
|
+
default: 20
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
const { gutters, queryVisible, footerVisible, footerFixed, upperSlots, downSlots, padding } = props
|
|
60
|
+
|
|
61
|
+
const footerHeight = ref(0)
|
|
62
|
+
onMounted(() => {
|
|
63
|
+
if (footerFixed) {
|
|
64
|
+
const height = document.querySelector('.page-footer')?.clientHeight || 0
|
|
16
65
|
|
|
17
|
-
|
|
18
|
-
name: "PageContainer",
|
|
19
|
-
props: {
|
|
20
|
-
gutters: {
|
|
21
|
-
type: Number,
|
|
22
|
-
default: 2
|
|
23
|
-
},
|
|
24
|
-
queryVisible: {
|
|
25
|
-
type: Boolean,
|
|
26
|
-
default: true
|
|
27
|
-
},
|
|
28
|
-
footerVisible: {
|
|
29
|
-
type: Boolean,
|
|
30
|
-
default: true
|
|
31
|
-
}
|
|
66
|
+
footerHeight.value = height
|
|
32
67
|
}
|
|
33
68
|
})
|
|
34
|
-
export default class PageContainer extends Vue {
|
|
35
|
-
gutters: unknown
|
|
36
|
-
queryVisible: unknown
|
|
37
|
-
footerVisible: unknown
|
|
38
|
-
}
|
|
39
69
|
</script>
|
|
40
70
|
<style lang="scss" scoped>
|
|
41
|
-
.page-
|
|
42
|
-
|
|
43
|
-
|
|
71
|
+
.page-container {
|
|
72
|
+
position: relative;
|
|
73
|
+
z-index: 1;
|
|
44
74
|
}
|
|
45
75
|
|
|
46
|
-
.
|
|
47
|
-
|
|
48
|
-
background-color: #fff;
|
|
76
|
+
.part-bg {
|
|
77
|
+
background-color: rgba(255, 255, 255, .65);
|
|
49
78
|
}
|
|
50
79
|
|
|
51
80
|
.page-footer {
|
|
52
81
|
display: flex;
|
|
53
82
|
justify-content: flex-end;
|
|
54
|
-
|
|
55
|
-
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.footer-fixed {
|
|
86
|
+
position: fixed;
|
|
87
|
+
left: 0;
|
|
88
|
+
bottom: 0;
|
|
89
|
+
width: 100%;
|
|
90
|
+
z-index: 999;
|
|
56
91
|
}
|
|
57
92
|
</style>
|
package/XklButton.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<real-el-button v-if="
|
|
2
|
+
<real-el-button v-if="doAuth(auth)" @click.prevent="btnClick">
|
|
3
3
|
<slot></slot>
|
|
4
4
|
</real-el-button>
|
|
5
5
|
</template>
|
|
@@ -14,17 +14,33 @@ import { componentGlobal } from '@xuekl/cli-base/global'
|
|
|
14
14
|
import { isAuth } from '@/utils'
|
|
15
15
|
import { useAttrs } from 'vue'
|
|
16
16
|
import { ElMessageBox } from 'element-plus'
|
|
17
|
+
import { useRoute } from 'vue-router'
|
|
17
18
|
|
|
18
|
-
const props = defineProps(['auth', 'prevent'])
|
|
19
|
-
const emit = defineEmits(['
|
|
19
|
+
const props = defineProps(['auth', 'prevent', 'openType', 'name'])
|
|
20
|
+
const emit = defineEmits(['async'])
|
|
21
|
+
const route = useRoute()
|
|
22
|
+
|
|
23
|
+
const { auth, name } = props
|
|
24
|
+
|
|
25
|
+
const doAuth = (auth) => {
|
|
26
|
+
if (name) {
|
|
27
|
+
return isAuth(route.name + ':' + name)
|
|
28
|
+
} else {
|
|
29
|
+
return isAuth(auth)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
20
32
|
|
|
21
|
-
const { auth } = props
|
|
22
33
|
|
|
23
34
|
const attrs = useAttrs()
|
|
24
35
|
let preventClick = false
|
|
25
36
|
|
|
26
37
|
const btnClick = () => {
|
|
27
|
-
|
|
38
|
+
if (attrs.click) {
|
|
39
|
+
attrs.onClick()
|
|
40
|
+
if (props.openType) {
|
|
41
|
+
window[props.openType] && window[props.openType]()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
28
44
|
if (componentGlobal.enableSubmit) {
|
|
29
45
|
preventClick = false
|
|
30
46
|
componentGlobal.enableSubmit = false
|
|
@@ -32,13 +48,21 @@ const btnClick = () => {
|
|
|
32
48
|
if (!preventClick) {
|
|
33
49
|
preventClick = true
|
|
34
50
|
emit('async', () => {
|
|
35
|
-
setTimeout(() =>
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
preventClick = false;
|
|
53
|
+
if (props.openType) {
|
|
54
|
+
window[props.openType] && window[props.openType]()
|
|
55
|
+
}
|
|
56
|
+
}, 200)
|
|
36
57
|
})
|
|
37
58
|
}
|
|
38
59
|
|
|
39
60
|
if (attrs.onConfirm) {
|
|
40
61
|
if (props.prevent === false) {
|
|
41
62
|
attrs.onConfirm()
|
|
63
|
+
if (props.openType) {
|
|
64
|
+
window[props.openType] && window[props.openType]()
|
|
65
|
+
}
|
|
42
66
|
} else {
|
|
43
67
|
ElMessageBox.confirm(
|
|
44
68
|
'当前内容可能存在修改,确认继续?',
|
|
@@ -50,9 +74,16 @@ const btnClick = () => {
|
|
|
50
74
|
}
|
|
51
75
|
).then(() => {
|
|
52
76
|
attrs.onConfirm()
|
|
77
|
+
if (props.openType) {
|
|
78
|
+
window[props.openType] && window[props.openType]()
|
|
79
|
+
}
|
|
53
80
|
}).catch(() => {
|
|
54
81
|
})
|
|
55
82
|
}
|
|
83
|
+
} else {
|
|
84
|
+
if (props.openType) {
|
|
85
|
+
window[props.openType] && window[props.openType]()
|
|
86
|
+
}
|
|
56
87
|
}
|
|
57
88
|
}
|
|
58
89
|
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<real-el-dropdown-item v-if="doAuth(auth)">
|
|
3
|
+
<slot></slot>
|
|
4
|
+
</real-el-dropdown-item>
|
|
5
|
+
</template>
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
export default {
|
|
8
|
+
name: 'ElDropdownItem'
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import { ElDropdownItem as RealElDropdownItem } from 'element-plus'
|
|
13
|
+
import { isAuth } from '@/utils'
|
|
14
|
+
import { useRoute } from 'vue-router'
|
|
15
|
+
const props = defineProps(['auth', 'name'])
|
|
16
|
+
const route = useRoute()
|
|
17
|
+
|
|
18
|
+
const { auth, name } = props
|
|
19
|
+
|
|
20
|
+
const doAuth = (auth) => {
|
|
21
|
+
if (name) {
|
|
22
|
+
return isAuth(route.name + ':' + name)
|
|
23
|
+
} else {
|
|
24
|
+
return isAuth(auth)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
</script>
|
package/XklForm.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-form ref="XklFormRef" :model="form" :label-width="opts.labelWidth"
|
|
2
|
+
<el-form ref="XklFormRef" :model="form" :label-width="opts.labelWidth" v-bind="formProps"
|
|
3
|
+
@keyup.enter.native="enterSubmit()">
|
|
3
4
|
<div class="hide-input">
|
|
4
5
|
<input type="text" />
|
|
5
6
|
<input type="password" />
|
|
@@ -75,7 +76,7 @@ import XklSelect from './XklSelect.vue'
|
|
|
75
76
|
import XklTreeSelect from './XklTreeSelect.vue'
|
|
76
77
|
import XklDict from './XklDict.vue'
|
|
77
78
|
import XklDatePicker from './XklDatePicker.vue'
|
|
78
|
-
import {
|
|
79
|
+
import { formConf } from './index'
|
|
79
80
|
|
|
80
81
|
const props = defineProps(['form'])
|
|
81
82
|
const emit = defineEmits(['enter'])
|
|
@@ -89,6 +90,8 @@ if (typeof opts.defaultCollapse !== 'undefined') {
|
|
|
89
90
|
isCollapse.value = opts.defaultCollapse
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
const formProps = Object.assign({}, formConf?.element, opts.element)
|
|
94
|
+
|
|
92
95
|
const enterSubmit = () => {
|
|
93
96
|
emit('enter')
|
|
94
97
|
}
|
|
@@ -190,21 +193,22 @@ formList.value.forEach(res => {
|
|
|
190
193
|
|
|
191
194
|
let stepLength = 0
|
|
192
195
|
let collapseTotalSpan = 0
|
|
196
|
+
|
|
193
197
|
if (opts.collapsible) {
|
|
194
198
|
let step = 0
|
|
195
199
|
for (let i = 0; i < spans.length; i++) {
|
|
196
|
-
if (step >= 24) {
|
|
197
|
-
stepLength = i
|
|
198
|
-
break
|
|
199
|
-
}
|
|
200
200
|
if (spans[i] === 24) {
|
|
201
201
|
step = step + 0
|
|
202
202
|
} else {
|
|
203
203
|
step = step + spans[i]
|
|
204
204
|
}
|
|
205
|
+
if (step >= 24) {
|
|
206
|
+
stepLength = i
|
|
207
|
+
break
|
|
208
|
+
}
|
|
205
209
|
}
|
|
206
210
|
|
|
207
|
-
for (let i = 0; i < stepLength
|
|
211
|
+
for (let i = 0; i < stepLength; i++) {
|
|
208
212
|
collapseTotalSpan = collapseTotalSpan + spans[i]
|
|
209
213
|
}
|
|
210
214
|
|
|
@@ -212,7 +216,7 @@ if (opts.collapsible) {
|
|
|
212
216
|
|
|
213
217
|
if (opts.collapsible) {
|
|
214
218
|
searchSpan.value = 24 - collapseTotalSpan % 24
|
|
215
|
-
formList.value = sourceFormList.slice(0, stepLength
|
|
219
|
+
formList.value = sourceFormList.slice(0, stepLength)
|
|
216
220
|
} else {
|
|
217
221
|
searchSpan.value = 24 - toalSpan % 24
|
|
218
222
|
formList.value = sourceFormList
|
|
@@ -224,7 +228,7 @@ const doCollapse = () => {
|
|
|
224
228
|
isCollapse.value = !isCollapse.value
|
|
225
229
|
if (isCollapse.value) {
|
|
226
230
|
searchSpan.value = 24 - collapseTotalSpan % 24
|
|
227
|
-
formList.value = sourceFormList.slice(0, stepLength
|
|
231
|
+
formList.value = sourceFormList.slice(0, stepLength)
|
|
228
232
|
} else {
|
|
229
233
|
searchSpan.value = 24 - toalSpan % 24
|
|
230
234
|
formList.value = sourceFormList
|
|
@@ -237,17 +241,8 @@ const regProto = () => {
|
|
|
237
241
|
let enableSubmit = true;
|
|
238
242
|
let submitTimer: NodeJS.Timeout
|
|
239
243
|
form.submit = (callback: (call: () => void, feils: any) => void) => {
|
|
240
|
-
if (componentGlobal.enableFormSubmit) {
|
|
241
|
-
enableSubmit = true
|
|
242
|
-
}
|
|
243
|
-
componentGlobal.enableFormSubmit = false
|
|
244
244
|
if (enableSubmit) {
|
|
245
245
|
enableSubmit = false;
|
|
246
|
-
clearTimeout(submitTimer)
|
|
247
|
-
submitTimer = setTimeout(() => {
|
|
248
|
-
componentGlobal.enableFormSubmit = true
|
|
249
|
-
enableSubmit = true
|
|
250
|
-
}, 3000)
|
|
251
246
|
sourceFormList.forEach(field => {
|
|
252
247
|
modeFields[field.prop] = (form as any)[field.prop]
|
|
253
248
|
});
|
package/XklFormInfo.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-form class="xkl-form-info" ref="XklFormInfoRef" :model="form"
|
|
2
|
+
<el-form class="xkl-form-info" :class="{ 'force-align-left': opts.forceAlignLeft }" ref="XklFormInfoRef" :model="form"
|
|
3
|
+
:label-width="opts.labelWidth">
|
|
3
4
|
<el-row>
|
|
4
5
|
<template v-for="item in formList" :key="item.prop">
|
|
5
6
|
<el-col :span="item.span" v-if="item.show()">
|
|
@@ -91,4 +92,10 @@ const dictLabel = computed(() => {
|
|
|
91
92
|
margin-bottom: 5px;
|
|
92
93
|
}
|
|
93
94
|
}
|
|
95
|
+
|
|
96
|
+
.force-align-left {
|
|
97
|
+
:deep(.el-form-item__label) {
|
|
98
|
+
width: auto !important;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
94
101
|
</style>
|
package/XklSelect.vue
CHANGED
|
@@ -27,11 +27,21 @@ const selectData = computed({
|
|
|
27
27
|
}
|
|
28
28
|
})
|
|
29
29
|
|
|
30
|
-
const changeHandle = (val: string) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
const changeHandle = (val: string | number | string[] | number[]) => {
|
|
31
|
+
if (Array.isArray(val)) {
|
|
32
|
+
const values = val.map(res => res.value)
|
|
33
|
+
const labels = val.map(res => res.label)
|
|
34
|
+
const items = dataList.value.filter(res => values.includes(res.value))
|
|
35
|
+
if (items) {
|
|
36
|
+
emit('update:label', labels)
|
|
37
|
+
emit('itemChange', items)
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
const item = dataList.value.find(res => res.value === val)
|
|
41
|
+
if (item) {
|
|
42
|
+
emit('update:label', item.label)
|
|
43
|
+
emit('itemChange', item)
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
46
|
}
|
|
37
47
|
|
package/XklTable.vue
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
align="center"></el-table-column>
|
|
12
12
|
<el-table-column v-if="table.index" type="index" align="center" v-bind="table.indexConfig"></el-table-column>
|
|
13
13
|
<el-table-column v-for=" item in table.columns " :key="item.prop" :prop="item.prop" :label="item.label"
|
|
14
|
-
:width="item.width" :align="item.align || 'center'" :sortable="item.sortable"
|
|
14
|
+
:width="item.width" :align="item.align || tableConf.defaultAlignment || 'center'" :sortable="item.sortable"
|
|
15
|
+
v-bind="item.element">
|
|
15
16
|
<template v-if="item.reflect" v-slot="{ row }">
|
|
16
17
|
{{ row[item.reflect] }}
|
|
17
18
|
</template>
|
package/XklUpload.vue
CHANGED
|
@@ -26,7 +26,8 @@ const { config, modelValue } = props
|
|
|
26
26
|
config.params = config.params || (() => { })
|
|
27
27
|
|
|
28
28
|
const headers = {
|
|
29
|
-
[config.authorization || 'Authorization']: getToken()
|
|
29
|
+
[config.authorization || 'Authorization']: getToken(),
|
|
30
|
+
...config.headers
|
|
30
31
|
}
|
|
31
32
|
const actionUrl = http.adornUrl(config.url || '/common/upload')
|
|
32
33
|
|