sh-view 2.9.8 → 2.9.10
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/package.json +11 -11
- package/packages/components/index.js +1 -7
- package/packages/components/sh-calendar/index.vue +2 -2
- package/packages/components/sh-date/index.vue +1 -1
- package/packages/components/sh-form/js/useForm.js +10 -3
- package/packages/components/sh-table/components/importModal.vue +7 -7
- package/packages/components/sh-table/grid.vue +1 -2
- package/packages/components/sh-table/js/props.js +7 -3
- package/packages/components/sh-table/js/tableMethods.js +42 -3
- package/packages/components/sh-table/js/useTable.js +38 -35
- package/packages/components/sh-table/table.vue +1 -2
- package/packages/components/sh-tree/components/table-tree.vue +48 -108
- package/packages/components/sh-tree/index.vue +127 -38
- package/packages/css/theme.scss +4 -0
- package/packages/vxeTable/css/index.scss +18 -24
- package/packages/vxeTable/index.js +81 -49
- package/packages/vxeTable/render/cell/vxe-render-checkgroup.vue +4 -4
- package/packages/vxeTable/render/cell/vxe-render-goption.vue +3 -3
- package/packages/vxeTable/render/cell/vxe-render-img.vue +6 -2
- package/packages/vxeTable/render/cell/vxe-render-input.vue +2 -2
- package/packages/vxeTable/render/cell/vxe-render-money.vue +19 -3
- package/packages/vxeTable/render/cell/vxe-render-radiogroup.vue +4 -4
- package/packages/vxeTable/render/cell/vxe-render-select.vue +2 -2
- package/packages/vxeTable/render/cell/vxe-render-table.vue +7 -6
- package/packages/vxeTable/render/cell/vxe-render-time.vue +3 -3
- package/packages/vxeTable/render/cell/vxe-render-tree.vue +1 -1
- package/packages/vxeTable/render/footer/vxe-footer-input.vue +13 -3
- package/packages/vxeTable/render/footer/vxe-footer-money.vue +13 -3
- package/packages/vxeTable/render/globalRenders.jsx +73 -205
- package/packages/vxeTable/render/header/vxe-header-money.vue +1 -1
- package/packages/vxeTable/render/mixin/cell-hooks.js +47 -53
- package/packages/vxeTable/render/mixin/cell-props.js +2 -10
- package/packages/vxeTable/render/mixin/filter-hooks.js +3 -0
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<vxe-grid
|
|
4
|
-
v-else
|
|
2
|
+
<vxe-table
|
|
5
3
|
ref="tableRef"
|
|
6
|
-
:key="renderKey"
|
|
7
4
|
:class="{ 'sh-vxe-tree-table': true, 'is--hidecheck': globalConfig.checkHide }"
|
|
8
5
|
v-bind="tableConfigIn"
|
|
9
6
|
@radio-change="onRadioChange"
|
|
10
7
|
@checkbox-change="onSelectionChange"
|
|
11
8
|
@checkbox-all="onSelectionChange">
|
|
12
|
-
<
|
|
13
|
-
<
|
|
9
|
+
<vxe-column :field="labelField" :title="labelTitle || multiple ? '全部' : ''" :width="checkWidth" :type="multiple ? 'checkbox' : 'radio'" treeNode>
|
|
10
|
+
<template #default="scoped">
|
|
11
|
+
<span>{{ getTreeNodeCellContent(scoped) }}</span>
|
|
12
|
+
</template>
|
|
13
|
+
</vxe-column>
|
|
14
|
+
<template v-if="globalConfig.columns && globalConfig.columns.length > 0">
|
|
15
|
+
<template v-for="column in globalConfig.columns" :key="column.field">
|
|
16
|
+
<vxe-column v-bind="column"></vxe-column>
|
|
17
|
+
</template>
|
|
14
18
|
</template>
|
|
15
19
|
<template #empty>
|
|
16
20
|
<sh-empty :icon="emptyIcon" :content="emptyText"></sh-empty>
|
|
17
21
|
</template>
|
|
18
|
-
</vxe-
|
|
22
|
+
</vxe-table>
|
|
19
23
|
</template>
|
|
20
24
|
|
|
21
25
|
<script>
|
|
22
26
|
import { defineComponent, computed, getCurrentInstance, ref, watch, onMounted } from 'vue'
|
|
23
27
|
// 树组件表格默认配置
|
|
24
28
|
const tableConfigDefault = {
|
|
29
|
+
fit: true,
|
|
25
30
|
autoResize: true,
|
|
26
31
|
stripe: false,
|
|
32
|
+
minHeight: 80,
|
|
27
33
|
size: 'small', // medium / small / mini
|
|
28
34
|
border: 'inner',
|
|
29
35
|
showHeader: false,
|
|
@@ -31,8 +37,8 @@ const tableConfigDefault = {
|
|
|
31
37
|
showOverflow: true,
|
|
32
38
|
resizeConfig: { refreshDelay: 100 },
|
|
33
39
|
columnConfig: { width: 120 },
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
virtualXConfig: { enabled: true, gt: 20 },
|
|
41
|
+
virtualYConfig: { enabled: true, gt: 20 }
|
|
36
42
|
}
|
|
37
43
|
import mixinProps from '../mixin/treeProps'
|
|
38
44
|
export default defineComponent({
|
|
@@ -47,37 +53,27 @@ export default defineComponent({
|
|
|
47
53
|
const { emit, slots } = context
|
|
48
54
|
|
|
49
55
|
const tableRef = ref()
|
|
50
|
-
const renderKey = ref(1)
|
|
51
56
|
const filterData = ref(null)
|
|
52
|
-
const treeServerComplate = ref(false)
|
|
53
|
-
const treeLoading = ref(false)
|
|
54
|
-
const treeData = ref(props.options)
|
|
55
57
|
const treeValue = ref([])
|
|
56
|
-
const queryCacheParams = ref(null)
|
|
57
|
-
const queryErrorText = ref(null)
|
|
58
58
|
|
|
59
59
|
const checkWidth = computed(() => {
|
|
60
60
|
return props.globalConfig.columns ? props.globalConfig?.defaultWidth || 150 : '100%'
|
|
61
61
|
})
|
|
62
|
-
|
|
63
|
-
let resultProps = { field: props.labelField, width: checkWidth.value, type: props.multiple ? 'checkbox' : 'radio', treeNode: true, slots: { default: 'treeNodeCell' } }
|
|
64
|
-
resultProps.title = props.labelTitle || props.multiple ? '全部' : ''
|
|
65
|
-
return resultProps
|
|
66
|
-
})
|
|
62
|
+
|
|
67
63
|
const tableProps = computed(() => {
|
|
68
64
|
return {
|
|
69
65
|
height: props.isSelect ? '100%' : props.height,
|
|
70
66
|
size: props.size,
|
|
71
|
-
loading: props.loading
|
|
72
|
-
data: filterData.value ||
|
|
73
|
-
columns: [checkColumnProps.value].concat(props.globalConfig?.columns || [])
|
|
67
|
+
loading: props.loading,
|
|
68
|
+
data: filterData.value || props.options
|
|
74
69
|
}
|
|
75
70
|
})
|
|
71
|
+
|
|
76
72
|
const tableConfigIn = computed(() => {
|
|
77
73
|
let resultConfig = {
|
|
78
|
-
rowConfig: {
|
|
79
|
-
radioConfig: {
|
|
80
|
-
checkboxConfig: {
|
|
74
|
+
rowConfig: { keyField: props.nodeKey },
|
|
75
|
+
radioConfig: { labelField: props.labelField, checkMethod: tableCheckMethods },
|
|
76
|
+
checkboxConfig: { labelField: props.labelField, checkMethod: tableCheckMethods },
|
|
81
77
|
treeConfig: { rowField: props.nodeKey },
|
|
82
78
|
editConfig: { enabled: false }
|
|
83
79
|
}
|
|
@@ -91,68 +87,31 @@ export default defineComponent({
|
|
|
91
87
|
return Object.assign(resultConfig, tableProps.value)
|
|
92
88
|
})
|
|
93
89
|
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
await getServerConfigDataSourse()
|
|
97
|
-
initSelection()
|
|
98
|
-
}
|
|
99
|
-
// 获取请求配置数据
|
|
100
|
-
const getServerConfigDataSourse = async () => {
|
|
101
|
-
const { serverConfig, serverParams, parseParams, serverCache, valueData, globalConfig, multiple, nodeKey, labelField } = props
|
|
102
|
-
if (!serverConfig.url) {
|
|
103
|
-
treeServerComplate.value = true
|
|
104
|
-
return true
|
|
105
|
-
}
|
|
106
|
-
let params = $vUtils.clone(serverParams, true)
|
|
107
|
-
if (parseParams && typeof parseParams === 'function') {
|
|
108
|
-
params = parseParams(params)
|
|
109
|
-
}
|
|
110
|
-
Object.keys(params).forEach(key => {
|
|
111
|
-
if ($vUtils.getFormatKeys(params[key]).length > 0) {
|
|
112
|
-
params[key] = $vUtils.format(params[key], valueData)
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
if (!$vUtils.isEqual(queryCacheParams.value, params)) {
|
|
116
|
-
treeServerComplate.value = false
|
|
117
|
-
}
|
|
118
|
-
if (serverCache && treeServerComplate.value) {
|
|
119
|
-
return true
|
|
120
|
-
}
|
|
121
|
-
queryErrorText.value = null
|
|
122
|
-
queryCacheParams.value = params
|
|
123
|
-
treeLoading.value = true
|
|
124
|
-
let reqOptions = {
|
|
125
|
-
baseURL: serverConfig.baseURL
|
|
126
|
-
}
|
|
127
|
-
try {
|
|
128
|
-
let method = serverConfig?.type ? serverConfig.type.toLowerCase() : 'post'
|
|
129
|
-
let treeRes = await $http[method](serverConfig.url, params, reqOptions)
|
|
130
|
-
if (treeRes && [10000, 100000].includes(+treeRes.code)) {
|
|
131
|
-
let treeAllNode = globalConfig?.hasAll && !multiple ? [{ [nodeKey]: 0, [labelField]: '全部', isleaf: 1, code: '' }] : []
|
|
132
|
-
let treeResData = treeAllNode.concat(treeRes.data)
|
|
133
|
-
if (globalConfig?.treeConfig?.transform) {
|
|
134
|
-
treeResData = $vUtils.toTreeArray(treeResData, { clear: true })
|
|
135
|
-
}
|
|
136
|
-
treeData.value = treeResData
|
|
137
|
-
} else {
|
|
138
|
-
throw new Error(`树节点信息获取失败:${treeRes?.message}`)
|
|
139
|
-
}
|
|
140
|
-
} catch (e) {
|
|
141
|
-
queryErrorText.value = e.message || e
|
|
142
|
-
}
|
|
143
|
-
treeLoading.value = false
|
|
144
|
-
treeServerComplate.value = true
|
|
145
|
-
}
|
|
146
|
-
const initSelection = isWatch => {
|
|
147
|
-
let { modelValue, isSelect } = props
|
|
90
|
+
const initSelection = () => {
|
|
91
|
+
let { modelValue, multiple } = props
|
|
148
92
|
let nodeKey = props.nodeKey || 'id'
|
|
149
93
|
setTimeout(() => {
|
|
150
94
|
if (!tableRef.value || !modelValue?.length) return
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
95
|
+
let tableFullData = tableRef.value.getTableData().fullData
|
|
96
|
+
let checkRows = []
|
|
97
|
+
$vUtils.eachTree(tableFullData, item => {
|
|
98
|
+
if (props.modelValue.includes(item[nodeKey])) {
|
|
99
|
+
checkRows.push(item)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
// 找到第一个选中节点的所有父级,进行展开
|
|
103
|
+
if (checkRows.length > 0) {
|
|
104
|
+
let expendNode = checkRows[0]
|
|
105
|
+
let checkParent = $vUtils.findTree(tableFullData, item => item[nodeKey] === expendNode[nodeKey])
|
|
106
|
+
let parentNodes = checkParent.nodes.filter(item => item[nodeKey] !== expendNode[nodeKey])
|
|
107
|
+
tableRef.value.setTreeExpand(parentNodes, true)
|
|
108
|
+
if (multiple) {
|
|
109
|
+
tableRef.value.setCheckboxRow(checkRows, true)
|
|
110
|
+
} else {
|
|
111
|
+
tableRef.value.setRadioRow(checkRows[0])
|
|
112
|
+
}
|
|
155
113
|
}
|
|
114
|
+
tableRef.value.scrollToRow({ [nodeKey]: modelValue[0] })
|
|
156
115
|
})
|
|
157
116
|
}
|
|
158
117
|
// 单选框变化
|
|
@@ -182,7 +141,7 @@ export default defineComponent({
|
|
|
182
141
|
}
|
|
183
142
|
// 全局搜索过滤事件
|
|
184
143
|
const handleMyTableFilter = text => {
|
|
185
|
-
const { labelField, labelFormat } = props
|
|
144
|
+
const { labelField, labelFormat, options } = props
|
|
186
145
|
let filterText = $vUtils.toValueString(text).trim().toLowerCase()
|
|
187
146
|
let searchData = null
|
|
188
147
|
if (filterText) {
|
|
@@ -195,7 +154,7 @@ export default defineComponent({
|
|
|
195
154
|
searchProps.push({ rkey: col.property, rname: renderObj.name, rprops: Object.assign({}, renderObj.props, col.rprops) })
|
|
196
155
|
}
|
|
197
156
|
})
|
|
198
|
-
searchData = $vUtils.searchTree(
|
|
157
|
+
searchData = $vUtils.searchTree(options, row => {
|
|
199
158
|
return searchProps.some(item => {
|
|
200
159
|
let cellValue = $vUtils.get(row, item.rkey)
|
|
201
160
|
let { rtext } = $vUtils.formatRender(cellValue, item.rkey, row, item.rname, item.rprops, proxy)
|
|
@@ -243,34 +202,15 @@ export default defineComponent({
|
|
|
243
202
|
},
|
|
244
203
|
{ deep: true, immediate: true }
|
|
245
204
|
)
|
|
246
|
-
watch(
|
|
247
|
-
() => props.options,
|
|
248
|
-
nv => {
|
|
249
|
-
treeData.value = nv
|
|
250
|
-
},
|
|
251
|
-
{ immediate: true }
|
|
252
|
-
)
|
|
253
|
-
watch(
|
|
254
|
-
() => treeData.value,
|
|
255
|
-
nv => {
|
|
256
|
-
emit('datacall', nv)
|
|
257
|
-
},
|
|
258
|
-
{ immediate: true }
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
onMounted(() => {
|
|
262
|
-
initMounted()
|
|
263
|
-
})
|
|
264
205
|
|
|
265
206
|
return {
|
|
266
207
|
tableRef,
|
|
267
|
-
|
|
268
|
-
treeServerComplate,
|
|
269
|
-
queryErrorText,
|
|
208
|
+
checkWidth,
|
|
270
209
|
tableConfigIn,
|
|
271
210
|
onRadioChange,
|
|
272
211
|
onSelectionChange,
|
|
273
|
-
getTreeNodeCellContent
|
|
212
|
+
getTreeNodeCellContent,
|
|
213
|
+
initSelection
|
|
274
214
|
}
|
|
275
215
|
}
|
|
276
216
|
})
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
<vxe-input ref="filterInputRef" v-model="filterTextIn" class="sh-tree-filter-input" v-bind="filterInputConfigIn"></vxe-input>
|
|
13
13
|
</div>
|
|
14
14
|
<div class="sh-tree-select-dropdown">
|
|
15
|
-
<
|
|
15
|
+
<sh-result v-if="queryErrorText" class="sh-tree-result" type="error" :title="false" :text="queryErrorText"></sh-result>
|
|
16
|
+
<table-tree ref="tableTreeRef" v-else v-bind="tableTreeProps" @select="onChange"></table-tree>
|
|
16
17
|
</div>
|
|
17
18
|
</template>
|
|
18
19
|
</vxe-pulldown>
|
|
@@ -22,14 +23,15 @@
|
|
|
22
23
|
<vxe-input ref="filterInputRef" v-model="filterTextIn" class="sh-tree-filter-input" v-bind="filterInputConfigIn"></vxe-input>
|
|
23
24
|
</div>
|
|
24
25
|
<div class="sh-tree-content" :class="{ 'has-filter': filter }">
|
|
25
|
-
<
|
|
26
|
+
<sh-result v-if="queryErrorText" class="sh-tree-result" type="error" :title="false" :text="queryErrorText"></sh-result>
|
|
27
|
+
<table-tree ref="tableTreeRef" v-else v-bind="tableTreeProps" @select="onChange"></table-tree>
|
|
26
28
|
</div>
|
|
27
29
|
</template>
|
|
28
30
|
</div>
|
|
29
31
|
</template>
|
|
30
32
|
|
|
31
33
|
<script>
|
|
32
|
-
import { defineComponent, computed,
|
|
34
|
+
import { defineComponent, computed, onMounted, getCurrentInstance, ref, watch } from 'vue'
|
|
33
35
|
import './css/index.scss'
|
|
34
36
|
import mixinProps from './mixin/treeProps'
|
|
35
37
|
import tableTree from './components/table-tree.vue'
|
|
@@ -44,54 +46,38 @@ export default defineComponent({
|
|
|
44
46
|
emits: ['update:modelValue', 'change', 'focus', 'blur'],
|
|
45
47
|
setup(props, context) {
|
|
46
48
|
const { proxy } = getCurrentInstance()
|
|
47
|
-
const { $vUtils } = proxy
|
|
49
|
+
const { $vUtils, $http } = proxy
|
|
48
50
|
const { emit, slots } = context
|
|
49
51
|
|
|
50
52
|
const treeSelectRef = ref()
|
|
51
53
|
const treeSelectInputRef = ref()
|
|
52
54
|
const filterInputRef = ref()
|
|
55
|
+
const tableTreeRef = ref()
|
|
53
56
|
// 公共属性
|
|
54
57
|
const filterTextIn = ref(props.filterText)
|
|
55
58
|
const selectedKeys = ref([])
|
|
56
59
|
const selectedData = ref([])
|
|
57
60
|
const treeData = ref(props.options)
|
|
61
|
+
const treeServerComplate = ref(false)
|
|
62
|
+
const treeLoading = ref(false)
|
|
63
|
+
const isChange = ref(false)
|
|
64
|
+
const queryCacheParams = ref(null)
|
|
65
|
+
const queryErrorText = ref(null)
|
|
58
66
|
// 下拉专属属性
|
|
59
67
|
const pulldownDrop = ref(false) // 由于hidePanel延迟350ms关闭,体验不好,这里使用自定义开关
|
|
60
68
|
|
|
61
69
|
const wrapHeight = computed(() => ([100, '100%', 'auto'].includes(props.height) ? '100%' : 'auto'))
|
|
62
70
|
const checkConfig = computed(() => ({ disabled: props.disabled, size: props.size }))
|
|
63
71
|
const selectLabels = computed(() => {
|
|
64
|
-
let {
|
|
65
|
-
|
|
66
|
-
const endStrs = ['Id', '_id']
|
|
67
|
-
endStrs.forEach(end => {
|
|
68
|
-
if (String(field).endsWith(end)) {
|
|
69
|
-
prefixKey = field.replace(end, '')
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
if (valueKeys) {
|
|
73
|
-
const valueks = Array.isArray(valueKeys) ? valueKeys : valueKeys.split(',')
|
|
74
|
-
valueks.forEach(key => {
|
|
75
|
-
const keySplits = String(key).replace(/@/gi, prefixKey).split('=')
|
|
76
|
-
const toKey = keySplits[0]
|
|
77
|
-
const fromKey = keySplits[1] || toKey
|
|
78
|
-
let fromvalue = null
|
|
79
|
-
if (multiple) {
|
|
80
|
-
fromvalue = selectedData.value.map(item => $vUtils.get(item, fromKey))
|
|
81
|
-
} else {
|
|
82
|
-
fromvalue = $vUtils.get(selectedData.value[0], fromKey)
|
|
83
|
-
}
|
|
84
|
-
$vUtils.set(valueData, toKey, fromvalue)
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
if (selectedKeys.value && Array.isArray(selectedKeys.value) && selectedKeys.value.length > 0 && treeData.value && treeData.value.length > 0) {
|
|
72
|
+
let { multiple, format, split, labelField } = props
|
|
73
|
+
if (selectedKeys.value && Array.isArray(selectedKeys.value) && selectedKeys.value.length > 0) {
|
|
88
74
|
let selectRows = getSelectRowsByValue(selectedKeys.value)
|
|
89
75
|
let labelFieldList = selectRows.map(item => $vUtils.get(item, labelField))
|
|
90
|
-
if (
|
|
76
|
+
if (format) {
|
|
91
77
|
if (multiple) {
|
|
92
|
-
labelFieldList = selectedData.value.map(item => $vUtils.format(
|
|
78
|
+
labelFieldList = selectedData.value.map(item => $vUtils.format(format, item))
|
|
93
79
|
} else {
|
|
94
|
-
labelFieldList = [$vUtils.format(
|
|
80
|
+
labelFieldList = [$vUtils.format(format, selectedData.value[0])]
|
|
95
81
|
}
|
|
96
82
|
}
|
|
97
83
|
return labelFieldList.join(split)
|
|
@@ -108,12 +94,67 @@ export default defineComponent({
|
|
|
108
94
|
return Object.assign({ prefixIcon: 'vxe-icon-search', placeholder: '搜索', clearable: true, controls: false, transfer: true }, props.globalConfig?.filterInputConfig)
|
|
109
95
|
})
|
|
110
96
|
const tableTreeProps = computed(() => {
|
|
111
|
-
return Object.assign({}, props, { filterText: filterTextIn.value, modelValue: selectedKeys.value })
|
|
97
|
+
return Object.assign({}, props, { options: treeData.value, loading: props.loading || treeLoading.value, filterText: filterTextIn.value, modelValue: selectedKeys.value })
|
|
112
98
|
})
|
|
113
99
|
|
|
100
|
+
const initMounted = async () => {
|
|
101
|
+
if (!props.isSelect) {
|
|
102
|
+
// 初始化获取服务配置数据
|
|
103
|
+
await getServerConfigDataSourse()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 获取请求配置数据
|
|
108
|
+
const getServerConfigDataSourse = async () => {
|
|
109
|
+
const { serverConfig, serverParams, parseParams, serverCache, valueData, globalConfig, multiple, nodeKey, labelField } = props
|
|
110
|
+
if (!serverConfig.url) {
|
|
111
|
+
treeServerComplate.value = true
|
|
112
|
+
return true
|
|
113
|
+
}
|
|
114
|
+
let params = $vUtils.clone(serverParams, true)
|
|
115
|
+
if (parseParams && typeof parseParams === 'function') {
|
|
116
|
+
params = parseParams(params)
|
|
117
|
+
}
|
|
118
|
+
Object.keys(params).forEach(key => {
|
|
119
|
+
if ($vUtils.getFormatKeys(params[key]).length > 0) {
|
|
120
|
+
params[key] = $vUtils.format(params[key], Object.assign({}, valueData, { menuInfo: proxy.menuInfo, userInfo: proxy.userInfo }))
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
if (!$vUtils.isEqual(queryCacheParams.value, params)) {
|
|
124
|
+
treeServerComplate.value = false
|
|
125
|
+
}
|
|
126
|
+
if (serverCache && treeServerComplate.value) {
|
|
127
|
+
return true
|
|
128
|
+
}
|
|
129
|
+
queryErrorText.value = null
|
|
130
|
+
queryCacheParams.value = params
|
|
131
|
+
treeLoading.value = true
|
|
132
|
+
let reqOptions = {
|
|
133
|
+
baseURL: serverConfig.baseURL
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
let method = serverConfig?.type ? serverConfig.type.toLowerCase() : 'post'
|
|
137
|
+
let treeRes = await $http[method](serverConfig.url, params, reqOptions)
|
|
138
|
+
if (treeRes && [10000, 100000].includes(+treeRes.code)) {
|
|
139
|
+
let treeAllNode = globalConfig?.hasAll && !multiple ? [{ [nodeKey]: 0, [labelField]: '全部', isleaf: 1, code: '' }] : []
|
|
140
|
+
let treeResData = treeAllNode.concat(treeRes.data)
|
|
141
|
+
if (globalConfig?.treeConfig?.transform) {
|
|
142
|
+
treeResData = $vUtils.toTreeArray(treeResData, { clear: true })
|
|
143
|
+
}
|
|
144
|
+
treeData.value = treeResData
|
|
145
|
+
} else {
|
|
146
|
+
throw new Error(`树节点信息获取失败:${treeRes?.message}`)
|
|
147
|
+
}
|
|
148
|
+
} catch (e) {
|
|
149
|
+
queryErrorText.value = e.message || e
|
|
150
|
+
}
|
|
151
|
+
treeLoading.value = false
|
|
152
|
+
treeServerComplate.value = true
|
|
153
|
+
}
|
|
154
|
+
|
|
114
155
|
// 根据选中值返回选中节点信息
|
|
115
156
|
const getSelectRowsByValue = keys => {
|
|
116
|
-
const { nodeKey, globalConfig } = props
|
|
157
|
+
const { nodeKey, globalConfig, valueData } = props
|
|
117
158
|
let childKey = (globalConfig.treeConfig && globalConfig.treeConfig.childrenField) || proxy.$vTableSetup?.table?.treeConfig?.childrenField || 'children'
|
|
118
159
|
let selectRows = []
|
|
119
160
|
$vUtils.eachTree(
|
|
@@ -125,6 +166,10 @@ export default defineComponent({
|
|
|
125
166
|
},
|
|
126
167
|
{ children: childKey }
|
|
127
168
|
)
|
|
169
|
+
// 为了数据回显,补入当前数据
|
|
170
|
+
if (valueData && valueData[nodeKey] && keys.includes(valueData[nodeKey]) && !selectRows.find(row => row[nodeKey] === valueData[nodeKey])) {
|
|
171
|
+
selectRows.push(valueData)
|
|
172
|
+
}
|
|
128
173
|
return selectRows
|
|
129
174
|
}
|
|
130
175
|
// 获取选中数据
|
|
@@ -138,9 +183,15 @@ export default defineComponent({
|
|
|
138
183
|
await treeSelectRef.value.togglePanel()
|
|
139
184
|
pulldownDrop.value = true
|
|
140
185
|
if (filterInputRef.value) filterInputRef.value.focus()
|
|
186
|
+
// 初始化获取服务配置数据
|
|
187
|
+
await getServerConfigDataSourse()
|
|
188
|
+
if (tableTreeRef.value) {
|
|
189
|
+
tableTreeRef.value.initSelection()
|
|
190
|
+
}
|
|
141
191
|
}
|
|
142
192
|
// 树节点选择变换事件
|
|
143
193
|
const onChange = async (keys, rows, obj) => {
|
|
194
|
+
isChange.value = true
|
|
144
195
|
if (props.isSelect) {
|
|
145
196
|
if (!props.multiple) {
|
|
146
197
|
pulldownDrop.value = false
|
|
@@ -167,18 +218,20 @@ export default defineComponent({
|
|
|
167
218
|
}
|
|
168
219
|
// 下拉数清除事件
|
|
169
220
|
const onClear = () => {
|
|
221
|
+
isChange.value = true
|
|
222
|
+
selectedKeys.value = []
|
|
223
|
+
selectedData.value = []
|
|
170
224
|
onHidePanel()
|
|
171
225
|
}
|
|
172
|
-
// 表格数据回调
|
|
173
|
-
const onDataCall = datas => {
|
|
174
|
-
treeData.value = datas
|
|
175
|
-
}
|
|
176
226
|
// 回调focus事件
|
|
177
227
|
const emitFocus = obj => {
|
|
178
228
|
emit('focus', obj)
|
|
179
229
|
}
|
|
180
230
|
// 回调change事件
|
|
181
231
|
const emitChange = () => {
|
|
232
|
+
if (!isChange.value) {
|
|
233
|
+
return
|
|
234
|
+
}
|
|
182
235
|
emitValue()
|
|
183
236
|
emit('change', selectedKeys.value, selectedData.value)
|
|
184
237
|
}
|
|
@@ -188,9 +241,37 @@ export default defineComponent({
|
|
|
188
241
|
}
|
|
189
242
|
// 回调双向绑定
|
|
190
243
|
const emitValue = () => {
|
|
244
|
+
const { valueData, valueKeys, multiple, field, split } = props
|
|
245
|
+
// 用于适配选择树形下拉给多个字段赋值
|
|
246
|
+
if (valueKeys && selectedData.value.length > 0) {
|
|
247
|
+
let prefixKey = field
|
|
248
|
+
const endStrs = ['Id', '_id']
|
|
249
|
+
endStrs.forEach(end => {
|
|
250
|
+
if (field.endsWith(end)) {
|
|
251
|
+
prefixKey = field.replace(end, '')
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
const valueks = Array.isArray(valueKeys) ? valueKeys : valueKeys.split(',')
|
|
255
|
+
valueks.forEach(key => {
|
|
256
|
+
const keySplits = String(key).replace(/@/gi, prefixKey).split('=')
|
|
257
|
+
const toKey = keySplits[0]
|
|
258
|
+
const fromKey = keySplits[1] || toKey
|
|
259
|
+
let fromvalue = null
|
|
260
|
+
if (multiple) {
|
|
261
|
+
fromvalue = selectedData.value.map(item => $vUtils.get(item, fromKey))
|
|
262
|
+
} else {
|
|
263
|
+
fromvalue = $vUtils.get(selectedData.value[0], fromKey)
|
|
264
|
+
}
|
|
265
|
+
$vUtils.set(valueData, toKey, fromvalue)
|
|
266
|
+
})
|
|
267
|
+
}
|
|
191
268
|
emit('update:modelValue', selectedKeys.value)
|
|
192
269
|
}
|
|
193
270
|
|
|
271
|
+
onMounted(() => {
|
|
272
|
+
initMounted()
|
|
273
|
+
})
|
|
274
|
+
|
|
194
275
|
watch(
|
|
195
276
|
() => props.modelValue,
|
|
196
277
|
value => {
|
|
@@ -206,11 +287,19 @@ export default defineComponent({
|
|
|
206
287
|
deep: true
|
|
207
288
|
}
|
|
208
289
|
)
|
|
290
|
+
watch(
|
|
291
|
+
() => props.options,
|
|
292
|
+
nv => {
|
|
293
|
+
treeData.value = nv
|
|
294
|
+
},
|
|
295
|
+
{ immediate: true }
|
|
296
|
+
)
|
|
209
297
|
|
|
210
298
|
return {
|
|
211
299
|
treeSelectRef,
|
|
212
300
|
treeSelectInputRef,
|
|
213
301
|
filterInputRef,
|
|
302
|
+
tableTreeRef,
|
|
214
303
|
wrapHeight,
|
|
215
304
|
selectConfigIn,
|
|
216
305
|
selectInputConfigIn,
|
|
@@ -218,12 +307,12 @@ export default defineComponent({
|
|
|
218
307
|
filterInputConfigIn,
|
|
219
308
|
pulldownDrop,
|
|
220
309
|
tableTreeProps,
|
|
310
|
+
queryErrorText,
|
|
221
311
|
selectLabels,
|
|
222
312
|
getSelectionData,
|
|
223
313
|
onFocus,
|
|
224
314
|
onClear,
|
|
225
315
|
onHidePanel,
|
|
226
|
-
onDataCall,
|
|
227
316
|
onChange
|
|
228
317
|
}
|
|
229
318
|
}
|
package/packages/css/theme.scss
CHANGED
|
@@ -42,6 +42,10 @@
|
|
|
42
42
|
--vxe-ui-input-placeholder-color: var(--placeholder-color);
|
|
43
43
|
|
|
44
44
|
--vxe-ui-table-header-background-color: var(--bg-layout-color);
|
|
45
|
+
--vxe-ui-table-cell-padding-default: 6px;
|
|
46
|
+
--vxe-ui-table-cell-padding-medium: 4px;
|
|
47
|
+
--vxe-ui-table-cell-padding-small: 2px;
|
|
48
|
+
--vxe-ui-table-cell-padding-mini: 1px;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
// 默认主题
|
|
@@ -132,6 +132,23 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
|
|
|
132
132
|
|
|
133
133
|
// 表格
|
|
134
134
|
.vxe-table{
|
|
135
|
+
&.is--maximize{
|
|
136
|
+
padding: 0;
|
|
137
|
+
}
|
|
138
|
+
&.is--hidecheck{
|
|
139
|
+
.vxe-cell--checkbox,.vxe-cell--radio{
|
|
140
|
+
padding-left: 0;
|
|
141
|
+
}
|
|
142
|
+
.vxe-checkbox--label, .vxe-radio--label{
|
|
143
|
+
padding-left: 0;
|
|
144
|
+
}
|
|
145
|
+
.vxe-cell--radio .vxe-radio--icon, .vxe-radio .vxe-radio--icon,
|
|
146
|
+
.vxe-table--render-wrapper .vxe-cell .vxe-cell--checkbox .vxe-checkbox--icon{
|
|
147
|
+
width: 0;
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
font-size: 0;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
135
152
|
&.vxe-table--render-default{
|
|
136
153
|
font-family: inherit;
|
|
137
154
|
color: inherit;
|
|
@@ -163,29 +180,6 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
|
|
|
163
180
|
}
|
|
164
181
|
}
|
|
165
182
|
|
|
166
|
-
// 表格grid
|
|
167
|
-
.vxe-grid{
|
|
168
|
-
&.is--maximize{
|
|
169
|
-
padding: 0;
|
|
170
|
-
}
|
|
171
|
-
&.is--hidecheck{
|
|
172
|
-
.vxe-table--render-default{
|
|
173
|
-
.vxe-cell--checkbox,.vxe-cell--radio{
|
|
174
|
-
padding-left: 0;
|
|
175
|
-
}
|
|
176
|
-
.vxe-checkbox--label, .vxe-radio--label{
|
|
177
|
-
padding-left: 0;
|
|
178
|
-
}
|
|
179
|
-
.vxe-cell--radio .vxe-radio--icon, .vxe-radio .vxe-radio--icon,
|
|
180
|
-
.vxe-table--render-wrapper .vxe-cell .vxe-cell--checkbox .vxe-checkbox--icon{
|
|
181
|
-
width: 0;
|
|
182
|
-
overflow: hidden;
|
|
183
|
-
font-size: 0;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
183
|
// 渲染器
|
|
190
184
|
.vxe-filter{
|
|
191
185
|
&--wrap{
|
|
@@ -245,7 +239,7 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
|
|
|
245
239
|
// 自定义渲染器样式
|
|
246
240
|
.vxe-render--inner {
|
|
247
241
|
display: inline-block;
|
|
248
|
-
.vxe-input, .vxe-select{
|
|
242
|
+
.vxe-input, .vxe-select, .vxe-number-input{
|
|
249
243
|
width: 100%;
|
|
250
244
|
}
|
|
251
245
|
&.vxe-render--inner--readonly{
|