vue2-client 1.8.175 → 1.8.178
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 +2 -1
- package/src/base-client/components/common/CitySelect/CitySelect.vue +109 -10
- package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +19 -5
- package/src/base-client/components/common/XForm/XFormItem.vue +7 -2
- package/src/base-client/components/common/XFormTable/XFormTable.vue +91 -63
- package/src/base-client/components/common/XTree/XTree.vue +243 -17
- package/src/utils/formatter.js +13 -1
- package/vue.config.js +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue2-client",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.178",
|
|
4
4
|
"private": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"jspdf": "^2.5.1",
|
|
39
39
|
"lodash.clonedeep": "^4.5.0",
|
|
40
40
|
"lodash.get": "^4.4.2",
|
|
41
|
+
"lodash.debounce": "^4",
|
|
41
42
|
"mockjs": "^1.1.0",
|
|
42
43
|
"nprogress": "^0.2.0",
|
|
43
44
|
"qs": "^6.11.2",
|
|
@@ -50,6 +50,10 @@
|
|
|
50
50
|
</template>
|
|
51
51
|
|
|
52
52
|
<script>
|
|
53
|
+
import { mapState } from 'vuex'
|
|
54
|
+
import { runLogic } from '@vue2-client/services/api/common'
|
|
55
|
+
import { handleTree } from '@vue2-client/utils/util'
|
|
56
|
+
|
|
53
57
|
const viewArr = [
|
|
54
58
|
{
|
|
55
59
|
key: '省/直辖市',
|
|
@@ -63,6 +67,9 @@ const viewArr = [
|
|
|
63
67
|
}, {
|
|
64
68
|
key: '街道',
|
|
65
69
|
value: 'streetData',
|
|
70
|
+
}, {
|
|
71
|
+
key: '小区',
|
|
72
|
+
value: 'communityData',
|
|
66
73
|
}
|
|
67
74
|
]
|
|
68
75
|
export default {
|
|
@@ -78,6 +85,8 @@ export default {
|
|
|
78
85
|
areaData: [],
|
|
79
86
|
// 街道
|
|
80
87
|
streetData: [],
|
|
88
|
+
// 小区
|
|
89
|
+
communityData: [],
|
|
81
90
|
},
|
|
82
91
|
// model: {
|
|
83
92
|
// provinceModel: { name: '', code: '' },
|
|
@@ -89,6 +98,7 @@ export default {
|
|
|
89
98
|
{ name: '', code: '' },
|
|
90
99
|
{ name: '', code: '' },
|
|
91
100
|
{ name: '', code: '' },
|
|
101
|
+
{ name: '', code: '' },
|
|
92
102
|
{ name: '', code: '' }
|
|
93
103
|
],
|
|
94
104
|
// 控制标签
|
|
@@ -99,21 +109,35 @@ export default {
|
|
|
99
109
|
valueView: undefined
|
|
100
110
|
}
|
|
101
111
|
},
|
|
102
|
-
mounted () {
|
|
103
|
-
|
|
104
|
-
|
|
112
|
+
async mounted () {
|
|
113
|
+
await this.$appdata.getDivisionsOhChinaForTree().then(res => {
|
|
114
|
+
if (res) {
|
|
115
|
+
this.tagData.divisionsForTree = res
|
|
116
|
+
if (this.value) {
|
|
117
|
+
this.setValue(this.value, res)
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
runLogic('getOperatingAreas', {}, 'af-revenue').then(res => {
|
|
121
|
+
this.tagData.divisionsForTree = handleTree(res, 'code', 'parentcode')
|
|
122
|
+
if (this.value) {
|
|
123
|
+
this.setValue(this.value, res)
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
}
|
|
105
127
|
})
|
|
106
128
|
},
|
|
107
129
|
model: {
|
|
108
130
|
prop: 'value',
|
|
109
131
|
event: 'onChange'
|
|
110
132
|
},
|
|
111
|
-
computed: {
|
|
133
|
+
computed: {
|
|
134
|
+
...mapState('account', { currUser: 'user' })
|
|
135
|
+
},
|
|
112
136
|
props: {
|
|
113
|
-
// 页面渲染内容 默认 省市区街道 四个 所以是4
|
|
137
|
+
// 页面渲染内容 默认 省市区街道 四个 所以是4 5 是到小区
|
|
114
138
|
contexts: {
|
|
115
139
|
type: Number,
|
|
116
|
-
default:
|
|
140
|
+
default: 4
|
|
117
141
|
},
|
|
118
142
|
placeholder: {
|
|
119
143
|
type: String,
|
|
@@ -164,14 +188,75 @@ export default {
|
|
|
164
188
|
type: String,
|
|
165
189
|
default: undefined
|
|
166
190
|
},
|
|
191
|
+
// 用于仅用于展示
|
|
192
|
+
defaultValue: {
|
|
193
|
+
type: String,
|
|
194
|
+
default: undefined
|
|
195
|
+
},
|
|
167
196
|
// 用于v-model 绑定 code :最后一级的code address: 所有级拼接的地址
|
|
168
197
|
valueType: {
|
|
169
198
|
type: String,
|
|
170
|
-
default: '
|
|
199
|
+
default: 'code'
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
watch: {
|
|
203
|
+
value () {
|
|
204
|
+
if (!this.value && this.valueView) {
|
|
205
|
+
/// 兼容外层重置方法
|
|
206
|
+
this.model = [
|
|
207
|
+
{ name: '', code: '' },
|
|
208
|
+
{ name: '', code: '' },
|
|
209
|
+
{ name: '', code: '' },
|
|
210
|
+
{ name: '', code: '' },
|
|
211
|
+
{ name: '', code: '' }
|
|
212
|
+
]
|
|
213
|
+
this.getResultText(this.contexts)
|
|
214
|
+
}
|
|
171
215
|
}
|
|
172
216
|
},
|
|
173
|
-
watch: {},
|
|
174
217
|
methods: {
|
|
218
|
+
setValue (code, tree) {
|
|
219
|
+
const findNode = (code, tree) => {
|
|
220
|
+
for (let i = 0; i < tree.length; i++) {
|
|
221
|
+
if (tree[i].code === code) {
|
|
222
|
+
return tree[i]
|
|
223
|
+
} else if (tree[i].children && tree[i].children.length > 0) {
|
|
224
|
+
const node = findNode(code, tree[i].children)
|
|
225
|
+
if (node) {
|
|
226
|
+
return node
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const findParent = (code, tree, parent = null) => {
|
|
233
|
+
for (let i = 0; i < tree.length; i++) {
|
|
234
|
+
if (tree[i].code === code) {
|
|
235
|
+
return parent
|
|
236
|
+
} else if (tree[i].children && tree[i].children.length > 0) {
|
|
237
|
+
const node = findParent(code, tree[i].children, tree[i])
|
|
238
|
+
if (node) {
|
|
239
|
+
return node
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const node = findNode(code, tree)
|
|
246
|
+
if (node) {
|
|
247
|
+
this.model[this.contexts - 1].name = node.name
|
|
248
|
+
this.model[this.contexts - 1].code = node.code
|
|
249
|
+
let parent = findParent(code, tree)
|
|
250
|
+
for (let i = this.contexts - 2; i >= 0; i--) {
|
|
251
|
+
this.model[i].name = parent ? parent.name : null
|
|
252
|
+
this.model[i].code = parent ? parent.code : null
|
|
253
|
+
if (i < this.contexts - 1 && parent) {
|
|
254
|
+
parent = findParent(parent.code, tree)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
this.getResultText(this.contexts)
|
|
258
|
+
}
|
|
259
|
+
},
|
|
175
260
|
tagClick (e, item) {
|
|
176
261
|
if (e === '省/直辖市') {
|
|
177
262
|
// 如果是同一个标签
|
|
@@ -215,10 +300,22 @@ export default {
|
|
|
215
300
|
this.getResultText(3)
|
|
216
301
|
} else if (e === '街道') {
|
|
217
302
|
if (this.model[3].name !== item.name) {
|
|
303
|
+
this.tagData.communityData = item.children
|
|
218
304
|
this.model[3].name = item.name
|
|
219
305
|
this.model[3].code = item.code
|
|
306
|
+
|
|
307
|
+
this.model[4] = { name: '', code: '' }
|
|
308
|
+
}
|
|
309
|
+
if (this.contexts !== 4) {
|
|
310
|
+
this.activeKey = '小区'
|
|
220
311
|
}
|
|
221
312
|
this.getResultText(4)
|
|
313
|
+
} else if (e === '小区') {
|
|
314
|
+
if (this.model[4].name !== item.name) {
|
|
315
|
+
this.model[4].name = item.name
|
|
316
|
+
this.model[4].code = item.code
|
|
317
|
+
}
|
|
318
|
+
this.getResultText(5)
|
|
222
319
|
}
|
|
223
320
|
},
|
|
224
321
|
getResultText (tag) {
|
|
@@ -230,14 +327,16 @@ export default {
|
|
|
230
327
|
}
|
|
231
328
|
code = this.model[i].code ?? ''
|
|
232
329
|
}
|
|
233
|
-
this.valueView =
|
|
330
|
+
this.valueView = address.length === 0 ? undefined : address.join('')
|
|
234
331
|
if (tag === this.contexts) {
|
|
235
332
|
this.$refs.select.blur()
|
|
236
|
-
this.$emit('onChange', this.valueType === 'address' ? address.join('') : code)
|
|
333
|
+
// this.$emit('onChange', this.valueType === 'address' ? address.join('') : code)
|
|
334
|
+
this.$emit('onChange', code)
|
|
237
335
|
}
|
|
238
336
|
},
|
|
239
337
|
// 失去焦点回调
|
|
240
338
|
selectBlurHandle () {
|
|
339
|
+
console.log(this.model[this.contexts - 1])
|
|
241
340
|
if (!this.model[this.contexts - 1].code || this.model[this.contexts - 1].code === '') {
|
|
242
341
|
this.valueView = undefined
|
|
243
342
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
ref="selectForm"
|
|
6
6
|
:zIndex="1001"
|
|
7
7
|
:model="form"
|
|
8
|
-
|
|
9
|
-
:
|
|
8
|
+
v-bind="formItemLayout"
|
|
9
|
+
:layout="layout"
|
|
10
10
|
:rules="rules">
|
|
11
11
|
<a-row :gutter="16">
|
|
12
12
|
<x-form-item
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
:images="images"
|
|
20
20
|
:service-name="serviceName"
|
|
21
21
|
mode="新增/修改"
|
|
22
|
+
:layout="layout"
|
|
22
23
|
:get-data-params="getDataParams"
|
|
23
24
|
:env="env"
|
|
24
25
|
/>
|
|
@@ -118,7 +119,9 @@ export default {
|
|
|
118
119
|
// 待修改的数据集
|
|
119
120
|
modifyModelData: {},
|
|
120
121
|
// 当前环境
|
|
121
|
-
env: 'prod'
|
|
122
|
+
env: 'prod',
|
|
123
|
+
// 表单模式 horizontal | vertical | inline
|
|
124
|
+
layout: 'horizontal'
|
|
122
125
|
}
|
|
123
126
|
},
|
|
124
127
|
computed: {
|
|
@@ -158,6 +161,14 @@ export default {
|
|
|
158
161
|
return item.addOrEdit === 'version'
|
|
159
162
|
})
|
|
160
163
|
},
|
|
164
|
+
formItemLayout () {
|
|
165
|
+
return this.layout === 'horizontal'
|
|
166
|
+
? {
|
|
167
|
+
labelCol: { span: 4 },
|
|
168
|
+
wrapperCol: { span: 15 },
|
|
169
|
+
}
|
|
170
|
+
: {}
|
|
171
|
+
},
|
|
161
172
|
...mapState('account', { currUser: 'user' })
|
|
162
173
|
},
|
|
163
174
|
methods: {
|
|
@@ -166,9 +177,10 @@ export default {
|
|
|
166
177
|
configName, configContent, formItems, viewMode, isHandleFormKey = true,
|
|
167
178
|
showSubmitBtn = true, serviceName, isTableTemp = false, isKeyHandle = true,
|
|
168
179
|
modifyModelData = {}, businessType, title, fixedAddForm = {}, getDataParams = {},
|
|
169
|
-
simpleFormJsonData = {}, env = 'prod'
|
|
180
|
+
simpleFormJsonData = {}, env = 'prod', layout = 'horizontal'
|
|
170
181
|
} = params
|
|
171
182
|
this.loaded = false
|
|
183
|
+
this.layout = layout
|
|
172
184
|
this.configName = configName
|
|
173
185
|
this.configContent = configContent
|
|
174
186
|
if (typeof formItems === 'string') {
|
|
@@ -403,7 +415,9 @@ export default {
|
|
|
403
415
|
businessType: this.businessType,
|
|
404
416
|
serviceName: this.serviceName,
|
|
405
417
|
realForm: realForm,
|
|
406
|
-
currUserName: this.currUser.name
|
|
418
|
+
currUserName: this.currUser.name,
|
|
419
|
+
currUserId: this.currUser.id,
|
|
420
|
+
orgId: this.currUser.orgid
|
|
407
421
|
})
|
|
408
422
|
} else {
|
|
409
423
|
this.defaultSubmit(realForm)
|
|
@@ -277,7 +277,7 @@
|
|
|
277
277
|
v-else-if="attr.type === 'citySelect'"
|
|
278
278
|
:flex="attr.flex">
|
|
279
279
|
<a-form-model-item :ref="attr.model" :label="attr.name" :prop="attr.prop ? attr.prop : attr.model">
|
|
280
|
-
<citySelect v-model="form[attr.model]" ></citySelect>
|
|
280
|
+
<citySelect ref="citySelect" v-model="form[attr.model]" :contexts="attr.contexts" :value-type="attr.valueType" :default-value="form[attr.model]"></citySelect>
|
|
281
281
|
</a-form-model-item>
|
|
282
282
|
</x-form-col>
|
|
283
283
|
<!-- 地点搜索框 -->
|
|
@@ -393,6 +393,11 @@ export default {
|
|
|
393
393
|
type: Object,
|
|
394
394
|
default: undefined
|
|
395
395
|
},
|
|
396
|
+
// 布局
|
|
397
|
+
layout: {
|
|
398
|
+
type: String,
|
|
399
|
+
default: 'horizontal'
|
|
400
|
+
},
|
|
396
401
|
// 环境
|
|
397
402
|
env: {
|
|
398
403
|
type: String,
|
|
@@ -425,7 +430,7 @@ export default {
|
|
|
425
430
|
},
|
|
426
431
|
methods: {
|
|
427
432
|
init () {
|
|
428
|
-
if (this.mode === '新增/修改' && !this.attr.flex) {
|
|
433
|
+
if (this.mode === '新增/修改' && !this.attr.flex && this.layout === 'horizontal') {
|
|
429
434
|
this.attr.flex = {
|
|
430
435
|
xs: 24,
|
|
431
436
|
sm: 24,
|
|
@@ -1,70 +1,87 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<a-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
2
|
+
<a-row type="flex" :gutter="48">
|
|
3
|
+
<a-col :span="6" v-if="xTreeConfigName">
|
|
4
|
+
<x-tree
|
|
5
|
+
:config-name="xTreeConfigName"
|
|
6
|
+
:env="env"
|
|
7
|
+
@action="action"
|
|
8
|
+
@treeOnChecked="treeOnChecked"
|
|
9
|
+
ref="xtree"
|
|
10
|
+
></x-tree>
|
|
11
|
+
</a-col>
|
|
12
|
+
<a-col :span="xTreeConfigName?18:24">
|
|
13
|
+
<a-skeleton :loading="loading" :paragraph="{ rows: 4 }"/>
|
|
14
|
+
<div v-show="!loading">
|
|
15
|
+
<template v-if="!loadError">
|
|
16
|
+
<x-add-form
|
|
17
|
+
ref="xAddForm"
|
|
18
|
+
@afterSubmit="onAddOrEditSubmitAfterSubmit"
|
|
19
|
+
>
|
|
20
|
+
<template slot="groupFormItems" slot-scope="{form, model, rules, modifyModelData}">
|
|
21
|
+
<slot
|
|
22
|
+
name="groupFormItems"
|
|
23
|
+
:form="form"
|
|
24
|
+
:model="model"
|
|
25
|
+
:rules="rules"
|
|
26
|
+
:modifyModelData="modifyModelData"></slot>
|
|
27
|
+
</template>
|
|
28
|
+
</x-add-form>
|
|
29
|
+
<div v-if="crudTitle" class="crud_title">
|
|
30
|
+
{{ crudTitle }}
|
|
31
|
+
</div>
|
|
32
|
+
<x-form
|
|
33
|
+
ref="xForm"
|
|
34
|
+
style="margin-bottom: 14px;"
|
|
35
|
+
@onSubmit="onSearchSubmit">
|
|
36
|
+
<slot name="formBtnExpand"></slot>
|
|
37
|
+
</x-form>
|
|
38
|
+
<x-table
|
|
39
|
+
ref="xTable"
|
|
40
|
+
:fixedQueryForm="fixedQueryForm"
|
|
41
|
+
:queryParamsName="queryParamsName"
|
|
42
|
+
:query-params-json="queryParamsJson"
|
|
43
|
+
:show-pagination="showPagination"
|
|
44
|
+
@add="add"
|
|
45
|
+
@edit="edit"
|
|
46
|
+
@afterDelete="afterDelete"
|
|
47
|
+
@action="action"
|
|
48
|
+
@selectRow="selectRow"
|
|
49
|
+
@afterQuery="afterQuery"
|
|
50
|
+
@tempTableEdit="tempTableEdit">
|
|
51
|
+
<template slot="leftButton" slot-scope="{selectedRowKeys, selectedRows}">
|
|
52
|
+
<slot name="leftButton" :selectedRowKeys="selectedRowKeys" :selectedRows="selectedRows"></slot>
|
|
53
|
+
</template>
|
|
54
|
+
<template slot="button" slot-scope="{selectedRowKeys, selectedRows}">
|
|
55
|
+
<slot name="button" :selectedRowKeys="selectedRowKeys" :selectedRows="selectedRows"></slot>
|
|
56
|
+
</template>
|
|
57
|
+
<template slot="rightBtnExpand" slot-scope="{selectedRowKeys, selectedRows}">
|
|
58
|
+
<slot name="rightBtnExpand" :selectedRowKeys="selectedRowKeys" :selectedRows="selectedRows"></slot>
|
|
59
|
+
<a-tooltip title="收起查询条件">
|
|
60
|
+
<a-button @click="toggleIsFormShow">
|
|
61
|
+
<a-icon :style="iconStyle" type="vertical-align-top"/>
|
|
62
|
+
</a-button>
|
|
63
|
+
</a-tooltip>
|
|
64
|
+
</template>
|
|
65
|
+
<!-- 底部插槽 -->
|
|
66
|
+
<template slot="footer" slot-scope="{selectedRowKeys, selectedRows}">
|
|
67
|
+
<slot name="footer" :selectedRowKeys="selectedRowKeys" :selectedRows="selectedRows"></slot>
|
|
68
|
+
</template>
|
|
69
|
+
</x-table>
|
|
70
|
+
</template>
|
|
71
|
+
<template v-else>
|
|
72
|
+
<a-empty>
|
|
73
|
+
<span slot="description"> 页面配置不存在请联系系统管理员, </span>
|
|
74
|
+
</a-empty>
|
|
75
|
+
</template>
|
|
76
|
+
</div>
|
|
77
|
+
</a-col>
|
|
78
|
+
</a-row>
|
|
63
79
|
</template>
|
|
64
80
|
<script>
|
|
65
81
|
import XForm from '@vue2-client/base-client/components/common/XForm'
|
|
66
82
|
import XAddForm from '@vue2-client/base-client/components/common/XAddForm'
|
|
67
83
|
import XTable from '@vue2-client/base-client/components/common/XTable'
|
|
84
|
+
import XTree from '@vue2-client/base-client/components/common/XTree'
|
|
68
85
|
import XImportExcel from '@vue2-client/base-client/components/common/XImportExcel'
|
|
69
86
|
import { getConfigByName, getConfigByLogic, parseConfig } from '@vue2-client/services/api/common'
|
|
70
87
|
import { mapState } from 'vuex'
|
|
@@ -74,6 +91,7 @@ export default {
|
|
|
74
91
|
components: {
|
|
75
92
|
XTable,
|
|
76
93
|
XForm,
|
|
94
|
+
XTree,
|
|
77
95
|
XAddForm,
|
|
78
96
|
XImportExcel
|
|
79
97
|
},
|
|
@@ -120,6 +138,11 @@ export default {
|
|
|
120
138
|
type: Object,
|
|
121
139
|
default: null
|
|
122
140
|
},
|
|
141
|
+
// xTree 配置
|
|
142
|
+
xTreeConfigName: {
|
|
143
|
+
type: String,
|
|
144
|
+
default: null
|
|
145
|
+
},
|
|
123
146
|
// 业务逻辑名称, 通过logic获取表单表格配置
|
|
124
147
|
logicName: {
|
|
125
148
|
type: String,
|
|
@@ -128,7 +151,8 @@ export default {
|
|
|
128
151
|
// 执行logic传递的参数
|
|
129
152
|
logicParam: {
|
|
130
153
|
type: Object,
|
|
131
|
-
default: () => {
|
|
154
|
+
default: () => {
|
|
155
|
+
}
|
|
132
156
|
},
|
|
133
157
|
// 固定新增表单
|
|
134
158
|
fixedAddForm: {
|
|
@@ -250,7 +274,7 @@ export default {
|
|
|
250
274
|
serviceName: this.serviceName,
|
|
251
275
|
env: this.env,
|
|
252
276
|
form: this.$refs.xForm.form
|
|
253
|
-
|
|
277
|
+
})
|
|
254
278
|
}
|
|
255
279
|
this.loading = false
|
|
256
280
|
},
|
|
@@ -309,10 +333,14 @@ export default {
|
|
|
309
333
|
* @param record 本条数据
|
|
310
334
|
* @param id 数据标识
|
|
311
335
|
* @param actionType 操作类型
|
|
336
|
+
* @param fun 向上级传递的事件
|
|
312
337
|
*/
|
|
313
338
|
action (record, id, actionType, fun = 'action') {
|
|
314
339
|
this.$emit(fun, record, id, actionType)
|
|
315
340
|
},
|
|
341
|
+
treeOnChecked (checkedKeys, deepNodes, deepKeys) {
|
|
342
|
+
this.$emit('treeOnChecked', checkedKeys, deepNodes, deepKeys)
|
|
343
|
+
},
|
|
316
344
|
/**
|
|
317
345
|
* 新增按钮事件
|
|
318
346
|
*/
|
|
@@ -1,75 +1,301 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
|
|
3
|
+
import { computed, reactive, ref, watch, defineExpose } from 'vue'
|
|
4
|
+
import executeStrFunction from '@vue2-client/utils/runEvalFunction'
|
|
5
|
+
import store from '@vue2-client/store/modules/account'
|
|
6
|
+
import debounce from 'lodash.debounce'
|
|
7
|
+
|
|
8
|
+
const config = reactive({})
|
|
9
|
+
// 是否加载中
|
|
10
|
+
const spinning = ref(false)
|
|
11
|
+
// 选中的 key
|
|
12
|
+
const checkedKeys = ref([])
|
|
13
|
+
// 定义 tree 数据
|
|
14
|
+
const _treeData = ref([])
|
|
15
|
+
// 存储搜索结果的树数据
|
|
16
|
+
const filteredTreeData = ref([])
|
|
17
|
+
// 定义最深一层的 数据
|
|
18
|
+
const deepestNodes = ref([])
|
|
19
|
+
// 替换字段
|
|
20
|
+
let _replaceFields = reactive({ children: 'children', title: 'title', key: 'key' })
|
|
21
|
+
// 当前用户信息
|
|
22
|
+
const currentUser = computed(() => store.state.user)
|
|
23
|
+
// 暂存查询信息
|
|
24
|
+
const searchInfo = ref({})
|
|
2
25
|
const props = defineProps({
|
|
3
26
|
// 树数据
|
|
4
27
|
// example: [{ title: '标题', key: '1', children: []}]
|
|
5
28
|
treeData: {
|
|
6
29
|
type: Array,
|
|
7
|
-
required:
|
|
30
|
+
required: false
|
|
31
|
+
},
|
|
32
|
+
configName: {
|
|
33
|
+
type: String,
|
|
34
|
+
required: false
|
|
35
|
+
},
|
|
36
|
+
env: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: 'prod'
|
|
8
39
|
},
|
|
9
40
|
replaceFields: {
|
|
10
41
|
type: Object,
|
|
11
42
|
default: () => ({ children: 'children', title: 'title', key: 'key' })
|
|
12
43
|
}
|
|
13
44
|
})
|
|
45
|
+
// 监听 checkbox 选中 的变化
|
|
46
|
+
watch(checkedKeys, (checkedKeys) => {
|
|
47
|
+
// 筛选出最底层的数据 返回
|
|
48
|
+
const deepNodes = []
|
|
49
|
+
const deepKeys = []
|
|
50
|
+
checkedKeys.forEach(key => {
|
|
51
|
+
const node = deepestNodes.value.find(node => node[_replaceFields.key] === key)
|
|
52
|
+
if (node) {
|
|
53
|
+
deepNodes.push(node)
|
|
54
|
+
deepKeys.push(node[_replaceFields.key])
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
emit('treeOnChecked', checkedKeys, deepNodes, deepKeys)
|
|
58
|
+
}, { immediate: true })
|
|
59
|
+
//
|
|
60
|
+
// watch(() => props.replaceFields, (newReplaceFields) => {
|
|
61
|
+
// if (newReplaceFields) {
|
|
62
|
+
// Object.assign(_replaceFields, newReplaceFields)
|
|
63
|
+
// }
|
|
64
|
+
// }, { immediate: true })
|
|
65
|
+
// 如果有configName 要先获取配置
|
|
66
|
+
if (props.treeData && props.treeData.length > 0) {
|
|
67
|
+
_treeData.value = props.treeData
|
|
68
|
+
deepestNodes.value = getDeepestNodes(_treeData.value)
|
|
69
|
+
}
|
|
70
|
+
if (props.replaceFields) {
|
|
71
|
+
_replaceFields = props.replaceFields
|
|
72
|
+
}
|
|
73
|
+
if (props.configName) {
|
|
74
|
+
getConfigByName(props.configName, undefined, (x) => {
|
|
75
|
+
Object.assign(config, x)
|
|
76
|
+
Object.assign(_replaceFields, x.replaceFields)
|
|
77
|
+
if (x.treeData.indexOf('logic@') >= 0) {
|
|
78
|
+
// 如果数据源是 logic
|
|
79
|
+
getData()
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
}
|
|
14
83
|
|
|
15
84
|
const emit = defineEmits(['onSelect'])
|
|
16
85
|
|
|
17
86
|
function onSelect (keys, e) {
|
|
18
87
|
emit('onSelect', keys, e)
|
|
19
88
|
}
|
|
89
|
+
|
|
90
|
+
async function getData (param = {}) {
|
|
91
|
+
spinning.value = true
|
|
92
|
+
searchInfo.value = Object.assign(param, {
|
|
93
|
+
org_id: currentUser.value.orgid,
|
|
94
|
+
user_id: currentUser.value.id,
|
|
95
|
+
dep_id: currentUser.value.f_department_id
|
|
96
|
+
})
|
|
97
|
+
await runLogic(config.treeData.substring(6), searchInfo.value, config.serviceName, props.env === 'dev').then(res => {
|
|
98
|
+
_treeData.value = res
|
|
99
|
+
deepestNodes.value = getDeepestNodes(_treeData.value)
|
|
100
|
+
spinning.value = false
|
|
101
|
+
}).catch(e => {
|
|
102
|
+
console.error('获取数据失败:' + e)
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function reLoad () {
|
|
107
|
+
getData(searchInfo.value)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const debouncedSearch = debounce((value) => {
|
|
111
|
+
console.log('Search:', value)
|
|
112
|
+
// 在这里执行你的搜索逻辑
|
|
113
|
+
if (value) {
|
|
114
|
+
filteredTreeData.value = searchInTree(_treeData, value)
|
|
115
|
+
} else {
|
|
116
|
+
filteredTreeData.value = []
|
|
117
|
+
}
|
|
118
|
+
}, 233)
|
|
119
|
+
|
|
120
|
+
function onChange (e) {
|
|
121
|
+
const searchInput = e.target.value
|
|
122
|
+
debouncedSearch(searchInput)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function searchInTree (tree, keyword) {
|
|
126
|
+
return tree.reduce((acc, node) => {
|
|
127
|
+
if (node.title.includes(keyword)) {
|
|
128
|
+
acc.push(node)
|
|
129
|
+
} else if (node.children) {
|
|
130
|
+
const childResults = searchInTree(node.children, keyword)
|
|
131
|
+
if (childResults.length > 0) {
|
|
132
|
+
acc.push({
|
|
133
|
+
...node,
|
|
134
|
+
children: childResults
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return acc
|
|
139
|
+
}, [])
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function action (record, func) {
|
|
143
|
+
emit('action', record, record[_replaceFields.key], null, func)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function getDeepestNodes (treeData) {
|
|
147
|
+
const deepestNodes = []
|
|
148
|
+
|
|
149
|
+
function traverse (node) {
|
|
150
|
+
if (!node[_replaceFields.children] || node[_replaceFields.children].length === 0) {
|
|
151
|
+
deepestNodes.push(node)
|
|
152
|
+
} else {
|
|
153
|
+
node[_replaceFields.children].forEach(child => traverse(child))
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
treeData.forEach(node => traverse(node))
|
|
158
|
+
return deepestNodes
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 使用 defineExpose 暴露方法
|
|
162
|
+
defineExpose({
|
|
163
|
+
reLoad
|
|
164
|
+
})
|
|
165
|
+
|
|
20
166
|
</script>
|
|
21
167
|
|
|
22
168
|
<template>
|
|
23
|
-
<div
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
169
|
+
<div id="XTreeWarp">
|
|
170
|
+
<div class="tree_title" :style="{height:config.search?'5rem':'3rem'}" v-if="config.title">
|
|
171
|
+
<a-row style="font-size: medium;line-height: 3rem">
|
|
172
|
+
<a-col :offset="2">
|
|
173
|
+
<span>{{ config.title }}</span>
|
|
174
|
+
</a-col>
|
|
175
|
+
</a-row>
|
|
176
|
+
<a-input-search
|
|
177
|
+
v-if="config.search"
|
|
178
|
+
style="margin-bottom: 8px"
|
|
179
|
+
placeholder="请输入搜索关键字"
|
|
180
|
+
@change="onChange"/>
|
|
181
|
+
</div>
|
|
182
|
+
<div
|
|
183
|
+
class="tree_main"
|
|
184
|
+
:style="{
|
|
185
|
+
maxHeight:config.search?'calc(100vh - 200px - 5rem)':'calc(100vh - 200px - 3rem)'
|
|
186
|
+
}">
|
|
187
|
+
<a-spin :spinning="spinning">
|
|
188
|
+
<a-tree
|
|
189
|
+
v-model="checkedKeys"
|
|
190
|
+
:tree-data="filteredTreeData && filteredTreeData.length> 0?filteredTreeData: _treeData"
|
|
191
|
+
:checkable="config.checkable"
|
|
192
|
+
:blockNode="true"
|
|
193
|
+
:replaceFields="_replaceFields"
|
|
194
|
+
:default-selected-keys="_treeData && _treeData.length > 0 ? [_treeData[0][_replaceFields.key]] : null"
|
|
195
|
+
:default-expand-all="true"
|
|
196
|
+
@select="onSelect"
|
|
197
|
+
>
|
|
198
|
+
<template slot="title" slot-scope="item">
|
|
199
|
+
<span>{{
|
|
200
|
+
item.dataRef[replaceFields.children] && item.dataRef[replaceFields.children].length > 0 ?
|
|
201
|
+
item[_replaceFields.title]
|
|
202
|
+
: config.deepNodeMaxWidth && item[_replaceFields.title].length > config.deepNodeMaxWidth ? item[_replaceFields.title].substring(0, config.deepNodeMaxWidth) + '...' : item[_replaceFields.title]
|
|
203
|
+
}}</span>
|
|
204
|
+
<a-space style="float:right;margin-right: .2rem">
|
|
205
|
+
<a-icon
|
|
206
|
+
v-for="icon in config.btn"
|
|
207
|
+
@click="action(item, icon.func)"
|
|
208
|
+
:key="icon.func"
|
|
209
|
+
v-if="executeStrFunction( icon.customFunction,[item])"
|
|
210
|
+
:type="icon.icon"
|
|
211
|
+
:style="{color:icon.color}"></a-icon>
|
|
212
|
+
</a-space>
|
|
213
|
+
</template>
|
|
214
|
+
</a-tree>
|
|
215
|
+
</a-spin>
|
|
216
|
+
</div>
|
|
31
217
|
</div>
|
|
32
218
|
</template>
|
|
33
219
|
|
|
34
220
|
<style lang="less" scoped>
|
|
221
|
+
.tree_title {
|
|
222
|
+
background-color: #E0E5EB;
|
|
223
|
+
border-radius: 8px 8px 0 0;
|
|
224
|
+
}
|
|
225
|
+
|
|
35
226
|
.tree_main {
|
|
36
|
-
:
|
|
227
|
+
width: 97%;
|
|
228
|
+
display: inline-block;
|
|
229
|
+
overflow-y: auto;
|
|
230
|
+
|
|
231
|
+
//:deep(.ant-tree-child-tree){
|
|
232
|
+
// .ant-space-item {
|
|
233
|
+
// display: none;
|
|
234
|
+
// }
|
|
235
|
+
//
|
|
236
|
+
// &:hover {
|
|
237
|
+
// .ant-space-item {
|
|
238
|
+
// display: block;
|
|
239
|
+
// }
|
|
240
|
+
// }
|
|
241
|
+
//}
|
|
242
|
+
|
|
243
|
+
:deep(.ant-tree li .ant-tree-node-content-wrapper) {
|
|
37
244
|
color: #000000e0;
|
|
38
245
|
}
|
|
246
|
+
|
|
247
|
+
:deep(.ant-tree-checkbox) {
|
|
248
|
+
top: .5rem !important;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
:deep(.ant-tree-node-content-wrapper ) {
|
|
252
|
+
display: inline;
|
|
253
|
+
}
|
|
254
|
+
|
|
39
255
|
:deep(.ant-tree li span.ant-tree-switcher, .ant-tree li span.ant-tree-iconEle) {
|
|
40
256
|
color: #0000004d;
|
|
257
|
+
|
|
41
258
|
i {
|
|
42
259
|
font-size: 16px !important;
|
|
43
260
|
line-height: 40px;
|
|
44
261
|
}
|
|
45
262
|
}
|
|
46
|
-
|
|
263
|
+
|
|
264
|
+
:deep(.ant-tree.ant-tree-directory > li span.ant-tree-node-content-wrapper::before, .ant-tree.ant-tree-directory .ant-tree-child-tree > li span.ant-tree-node-content-wrapper::before) {
|
|
47
265
|
height: 40px;
|
|
48
266
|
border-radius: 6px;
|
|
49
267
|
}
|
|
50
|
-
|
|
268
|
+
|
|
269
|
+
:deep(.ant-tree.ant-tree-directory > li.ant-tree-treenode-selected > span.ant-tree-node-content-wrapper::before) {
|
|
51
270
|
background: #e6f7ff;
|
|
52
271
|
}
|
|
53
|
-
|
|
272
|
+
|
|
273
|
+
:deep(.ant-tree.ant-tree-directory .ant-tree-child-tree > li.ant-tree-treenode-selected > span.ant-tree-node-content-wrapper::before) {
|
|
54
274
|
background: #e6f7ff;
|
|
55
275
|
}
|
|
56
|
-
|
|
276
|
+
|
|
277
|
+
:deep(.ant-tree.ant-tree-directory .ant-tree-child-tree > li.ant-tree-treenode-selected > span.ant-tree-switcher) {
|
|
57
278
|
color: #0000004d;
|
|
58
279
|
}
|
|
59
|
-
|
|
280
|
+
|
|
281
|
+
:deep(.ant-tree.ant-tree-directory > li span.ant-tree-node-content-wrapper.ant-tree-node-selected, .ant-tree.ant-tree-directory .ant-tree-child-tree > li span.ant-tree-node-content-wrapper.ant-tree-node-selected) {
|
|
60
282
|
color: #000000e0;
|
|
61
283
|
}
|
|
62
|
-
|
|
284
|
+
|
|
285
|
+
:deep(.ant-tree li .ant-tree-node-content-wrapper) {
|
|
63
286
|
line-height: 40px;
|
|
64
287
|
height: 40px;
|
|
65
288
|
}
|
|
289
|
+
|
|
66
290
|
:deep(.ant-tree li) {
|
|
67
291
|
padding-left: 4px;
|
|
68
292
|
}
|
|
293
|
+
|
|
69
294
|
:deep(.ant-tree ul) {
|
|
70
295
|
padding-left: 10px;
|
|
71
296
|
}
|
|
72
|
-
|
|
297
|
+
|
|
298
|
+
:deep(.ant-tree-icon__customize) {
|
|
73
299
|
display: none;
|
|
74
300
|
}
|
|
75
301
|
}
|
package/src/utils/formatter.js
CHANGED
|
@@ -65,4 +65,16 @@ function formatConfig (obj, dep) {
|
|
|
65
65
|
return `${prefix}${str}${subfix}`
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
function getRealKeyData (data) {
|
|
69
|
+
const obj = {}
|
|
70
|
+
Object.keys(data).forEach(k => {
|
|
71
|
+
if (k.indexOf('_') >= 0) {
|
|
72
|
+
obj[k.substring(k.indexOf('_') + 1)] = data[k]
|
|
73
|
+
} else {
|
|
74
|
+
obj[k] = data[k]
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
return obj
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = { formatConfig, getRealKeyData }
|
package/vue.config.js
CHANGED
|
@@ -42,6 +42,16 @@ module.exports = {
|
|
|
42
42
|
// target: testUpload,
|
|
43
43
|
// changeOrigin: true
|
|
44
44
|
// },
|
|
45
|
+
'/api/af-revenue/logic/openapi/': {
|
|
46
|
+
pathRewrite: { '^/api/af-revenue/logic/openapi/': '/logic/' },
|
|
47
|
+
target: 'http://127.0.0.1:9026',
|
|
48
|
+
changeOrigin: true
|
|
49
|
+
},
|
|
50
|
+
'/api/af-revenue': {
|
|
51
|
+
pathRewrite: { '^/api/af-revenue/': '/' },
|
|
52
|
+
target: 'http://127.0.0.1:9026',
|
|
53
|
+
changeOrigin: true
|
|
54
|
+
},
|
|
45
55
|
'/api': {
|
|
46
56
|
// v3用
|
|
47
57
|
// pathRewrite: { '^/api/af-system/': '/rs/', '^/api/af-iot/': '/rs/' },
|