@tongfun/tf-widget 0.1.21 → 0.1.22
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/README.md +49 -49
- package/lib/tf-widget.common.js +547 -503
- package/lib/tf-widget.css +1 -1
- package/lib/tf-widget.umd.js +547 -503
- package/lib/tf-widget.umd.min.js +4 -4
- package/package/svg-icon/index.js +8 -8
- package/package/svg-icon/src/SvgIcon.vue +59 -59
- package/package/t-data-list/index.js +6 -6
- package/package/t-data-list/main.vue +193 -193
- package/package/t-data-list/src/condition-input/basic.vue +31 -31
- package/package/t-data-list/src/condition-input/date.vue +106 -106
- package/package/t-data-list/src/condition-input/index.vue +100 -100
- package/package/t-data-list/src/condition-input/input.vue +31 -31
- package/package/t-data-list/src/condition-input/number.vue +115 -115
- package/package/t-data-list/src/condition-input/select.vue +86 -86
- package/package/t-data-list/src/js/fieldTypeEnum.js +10 -10
- package/package/t-data-list/src/js/operatorEnum.js +108 -108
- package/package/t-data-list/src/js/qureyParamsEnum.js +4 -4
- package/package/t-data-list/src/js/util.js +34 -34
- package/package/t-data-list/src/mixins/button-controll-mixin.js +93 -93
- package/package/t-data-list/src/pushdown/push-down.vue +158 -158
- package/package/t-data-list/src/t-list-search.vue +36 -36
- package/package/t-data-list/src/t-plan/condition-always-item.vue +143 -143
- package/package/t-data-list/src/t-plan/condition-mult-item.vue +222 -222
- package/package/t-data-list/src/t-plan/index.vue +195 -195
- package/package/t-data-list/src/t-plan/plan-content.vue +389 -389
- package/package/t-data-list/src/t-table/index.vue +129 -129
- package/package/t-data-list/src/t-table/table-group-item-edit.vue +238 -238
- package/package/t-data-list/src/t-table/table-group-item.vue +87 -87
- package/package/t-data-list/src/t-table/table-group.vue +180 -180
- package/package/t-data-list/src/t-table/table-records-header-popover.vue +246 -246
- package/package/t-data-list/src/t-table/table-records-selected.vue +159 -159
- package/package/t-data-list/src/t-table/table-records.vue +337 -337
- package/package/t-input/children/address.vue +101 -101
- package/package/t-input/children/basic-display.vue +41 -41
- package/package/t-input/children/basic.vue +253 -253
- package/package/t-input/children/date.vue +89 -89
- package/package/t-input/children/group-components/group-dialog.vue +344 -344
- package/package/t-input/children/group.vue +126 -126
- package/package/t-input/children/input.vue +72 -72
- package/package/t-input/children/number.vue +74 -74
- package/package/t-input/children/select.vue +89 -89
- package/package/t-input/children/tfile/fiile-enclosure.vue +233 -233
- package/package/t-input/index.js +7 -7
- package/package/t-input/index.vue +337 -337
- package/package/t-input/tInputCache.js +24 -24
- package/package/tf-icon-picker/README.md +7 -7
- package/package/tf-icon-picker/index.js +8 -8
- package/package/tf-icon-picker/src/tf-icon-picker.vue +266 -266
- package/package/tf-layout/README.md +115 -115
- package/package/tf-layout/index.js +8 -8
- package/package/tf-layout/src/components/tf-labelbar.vue +394 -394
- package/package/tf-layout/src/components/tf-menu.vue +180 -180
- package/package/tf-layout/src/components/tf-right-menu.vue +89 -89
- package/package/tf-layout/src/components/tf-rotate-box.vue +50 -50
- package/package/tf-layout/src/tf-layout.vue +140 -140
- package/package/tf-widget/index.js +8 -8
- package/package/tf-widget/src/assets/common-input.less +10 -10
- package/package/tf-widget/src/children/basic-data/basic-data.vue +361 -361
- package/package/tf-widget/src/children/basic-data/dependcy/basic-data-selector.vue +1087 -1087
- package/package/tf-widget/src/children/basic-data/dependcy/common-table.vue +750 -750
- package/package/tf-widget/src/children/basic-data/dependcy/condition-filter.vue +519 -519
- package/package/tf-widget/src/children/basic-data/dependcy/pagination.vue +93 -93
- package/package/tf-widget/src/children/basic-data/dependcy/table-control.vue +240 -240
- package/package/tf-widget/src/children/basic-data/dependcy/view-picture.vue +108 -108
- package/package/tf-widget/src/children/date-time.vue +103 -103
- package/package/tf-widget/src/children/date.vue +103 -103
- package/package/tf-widget/src/children/decimal.vue +115 -115
- package/package/tf-widget/src/children/integer.vue +104 -104
- package/package/tf-widget/src/children/property.vue +59 -59
- package/package/tf-widget/src/children/single-line-text.vue +82 -82
- package/package/tf-widget/src/children/small-pictures.vue +223 -223
- package/package/tf-widget/src/children/text-area.vue +74 -74
- package/package/tf-widget/src/children/tf-select.vue +113 -113
- package/package/tf-widget/src/tf-widget.vue +175 -175
- package/package.json +44 -44
- package/src/api/edit.js +97 -97
- package/src/api/file-enclosure.js +26 -26
- package/src/api/push-down.js +19 -19
- package/src/api/table.js +294 -294
- package/src/api/tableV3.js +166 -160
- package/src/assets/images/icons/index.js +9 -9
- package/src/assets/images/icons/svg/add.svg +5 -5
- package/src/assets/images/icons/svg/push-down.svg +1 -1
- package/src/assets/images/icons/svg/remove.svg +1 -1
- package/src/assets/styles/common-table.less +202 -202
- package/src/directives/debounce.js +24 -24
- package/src/index.js +31 -31
- package/src/mixins/t-data-query-mixin.js +290 -290
- package/src/utils/auth.js +22 -22
- package/src/utils/request.js +42 -42
- package/src/utils/stato-anormale.js +59 -59
- package/src/utils/utils.js +109 -109
- package/src/utils/validate.js +84 -84
|
@@ -1,389 +1,389 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div v-show="visible" v-clickoutside="handleClickOut" class="plan-content">
|
|
3
|
-
<!--
|
|
4
|
-
方案详情,包含名称,过滤条件
|
|
5
|
-
-->
|
|
6
|
-
<div class="plan-details">
|
|
7
|
-
<div class="plan-title">
|
|
8
|
-
<span class="title">方案名称:</span>
|
|
9
|
-
<el-input v-model="planContent.name" size="mini" />
|
|
10
|
-
<span class="error">{{ errorMsg }}</span>
|
|
11
|
-
</div>
|
|
12
|
-
|
|
13
|
-
<!-- 常用条件 -->
|
|
14
|
-
<div class="condition-always">
|
|
15
|
-
<span class="title">常用条件</span>
|
|
16
|
-
<el-scrollbar>
|
|
17
|
-
<ConditionAlwaysItem
|
|
18
|
-
v-for="item in planContent.schemeUsefulList"
|
|
19
|
-
:key="item.field"
|
|
20
|
-
v-model="item.values"
|
|
21
|
-
:data="item"
|
|
22
|
-
/>
|
|
23
|
-
</el-scrollbar>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<!--高级过滤条件 -->
|
|
27
|
-
<div class="plan-conditions">
|
|
28
|
-
<span class="title">高级查询</span>
|
|
29
|
-
<div>
|
|
30
|
-
<ConditionItem
|
|
31
|
-
v-for="condition in planContent.contentsList"
|
|
32
|
-
:key="condition.id"
|
|
33
|
-
:condition="condition"
|
|
34
|
-
@remove="removeCondition(condition)"
|
|
35
|
-
/>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
<div class="add-button" @click="addCondition">
|
|
39
|
-
<i class="el-icon-plus" />
|
|
40
|
-
<span>添加</span>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<!--
|
|
46
|
-
方案操作
|
|
47
|
-
-->
|
|
48
|
-
<div class="plan-buttons">
|
|
49
|
-
<div class="buttons">
|
|
50
|
-
<el-button type="primary" size="mini" @click="conditionChange">查询</el-button>
|
|
51
|
-
<el-button type="primary" size="mini" @click="update($event)">保存</el-button>
|
|
52
|
-
<el-button type="primary" size="mini" @click="add">保存为新方案</el-button>
|
|
53
|
-
<el-button type="primary" size="mini" :disabled="planContent.isDefault" @click="update($event,true)">保存为默认</el-button>
|
|
54
|
-
<el-button type="primary" size="mini" @click="deletePlan">删除方案</el-button>
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
</template>
|
|
59
|
-
<script>
|
|
60
|
-
import { getAllOverOperatorList } from '../js/operatorEnum'
|
|
61
|
-
import Clickoutside from 'element-ui/src/utils/clickoutside'
|
|
62
|
-
import ConditionItem from './condition-mult-item.vue'
|
|
63
|
-
import ConditionAlwaysItem from './condition-always-item.vue'
|
|
64
|
-
import { addPlan, deletePlan, updatePlan } from '@/api/tableV3.js'
|
|
65
|
-
export default {
|
|
66
|
-
components: {
|
|
67
|
-
ConditionItem,
|
|
68
|
-
ConditionAlwaysItem
|
|
69
|
-
},
|
|
70
|
-
directives: { Clickoutside },
|
|
71
|
-
props: {
|
|
72
|
-
visible: {
|
|
73
|
-
type: Boolean,
|
|
74
|
-
default: false
|
|
75
|
-
},
|
|
76
|
-
// 方案详情的内容
|
|
77
|
-
content: {
|
|
78
|
-
type: Object,
|
|
79
|
-
default: null
|
|
80
|
-
},
|
|
81
|
-
// 当前所有方案的名称
|
|
82
|
-
planNames: {
|
|
83
|
-
type: Array,
|
|
84
|
-
default: null
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
data () {
|
|
88
|
-
return {
|
|
89
|
-
errorMsg: '',
|
|
90
|
-
planContent: {
|
|
91
|
-
name: '',
|
|
92
|
-
schemeUsefulList: [],
|
|
93
|
-
contentsList: []
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
inject: ['target'],
|
|
98
|
-
watch: {
|
|
99
|
-
content (newValue) {
|
|
100
|
-
this.loadPlanContent(newValue)
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
methods: {
|
|
104
|
-
// 加载一个方案数据,处理方案的数据,并发射条件变更事件
|
|
105
|
-
loadPlanContent (content, immediate = false) {
|
|
106
|
-
const contentCopy = JSON.parse(JSON.stringify(content))
|
|
107
|
-
contentCopy.contentsList = contentCopy.contentsList || []
|
|
108
|
-
for (const alwaysItem of contentCopy.schemeUsefulList) {
|
|
109
|
-
if (!alwaysItem.values.length) {
|
|
110
|
-
alwaysItem.values.push('-1')
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
this.planContent = contentCopy
|
|
114
|
-
this.conditionChange()
|
|
115
|
-
},
|
|
116
|
-
// 点击方案内容外侧收起方案详情弹窗
|
|
117
|
-
handleClickOut () {
|
|
118
|
-
if (!this.visible) return
|
|
119
|
-
this.$emit('update:visible', false)
|
|
120
|
-
},
|
|
121
|
-
/**
|
|
122
|
-
* 添加一个高级过滤条件
|
|
123
|
-
*/
|
|
124
|
-
addCondition () {
|
|
125
|
-
const conditionModel = {
|
|
126
|
-
id: Math.random().toString(36).slice(8),
|
|
127
|
-
leftBracket: '(',
|
|
128
|
-
field: '',
|
|
129
|
-
operator: '',
|
|
130
|
-
value: '',
|
|
131
|
-
rightBracket: ')',
|
|
132
|
-
relation: 'AND',
|
|
133
|
-
fieldType: '',
|
|
134
|
-
userSchemeId: this.content.id
|
|
135
|
-
}
|
|
136
|
-
this.planContent.contentsList.push(conditionModel)
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* 删除一个高级过滤条件
|
|
141
|
-
*/
|
|
142
|
-
removeCondition (condition) {
|
|
143
|
-
const index = this.planContent.contentsList.indexOf(condition)
|
|
144
|
-
this.planContent.contentsList.splice(index, 1)
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* 条件前端校验
|
|
149
|
-
* 校验含有空值,以及括号是否闭合
|
|
150
|
-
*/
|
|
151
|
-
conditionValidate () {
|
|
152
|
-
const bracketStack = []
|
|
153
|
-
for (const condition of this.planContent.contentsList) {
|
|
154
|
-
if (!getAllOverOperatorList().includes(condition.operator) && !condition.value) {
|
|
155
|
-
this.$message.error('方案中存在没有填写内容的条件')
|
|
156
|
-
return false
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
bracketStack.push(...condition.leftBracket.split(''))
|
|
160
|
-
for (let i = 0; i < condition.rightBracket.length; i++) {
|
|
161
|
-
if (!bracketStack.pop()) {
|
|
162
|
-
this.$message.error('方案中条件的括号没有闭合')
|
|
163
|
-
return false
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (bracketStack.length) {
|
|
169
|
-
this.$message.error('方案中条件的括号没有闭合')
|
|
170
|
-
return false
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return true
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* 搜索按钮的处理函数
|
|
178
|
-
* 条件已经变更,将变更后的条件发射出去,父组件接受处理后使用新的条件调用接口查询数据
|
|
179
|
-
*/
|
|
180
|
-
conditionChange () {
|
|
181
|
-
if (!this.conditionValidate()) {
|
|
182
|
-
return
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// 常用条件格式化
|
|
186
|
-
const conditionAlways = []
|
|
187
|
-
for (const conditionAlwaysItem of this.planContent.schemeUsefulList) {
|
|
188
|
-
conditionAlways.push({
|
|
189
|
-
field: conditionAlwaysItem.field,
|
|
190
|
-
values: conditionAlwaysItem.values
|
|
191
|
-
})
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// 高级过滤条件格式化
|
|
195
|
-
const conditionMulti = []
|
|
196
|
-
const getQueryMultiConditonItem = function (sourceMultiItem, index) {
|
|
197
|
-
const keys = [
|
|
198
|
-
'leftBracket',
|
|
199
|
-
'field',
|
|
200
|
-
'operator',
|
|
201
|
-
'value',
|
|
202
|
-
'rightBracket',
|
|
203
|
-
'relation',
|
|
204
|
-
'fieldType'
|
|
205
|
-
]
|
|
206
|
-
const res = {}
|
|
207
|
-
res.sort = index
|
|
208
|
-
for (const key of keys) {
|
|
209
|
-
res[key] = sourceMultiItem[key]
|
|
210
|
-
}
|
|
211
|
-
return res
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
this.planContent.contentsList.forEach((item, index) => {
|
|
215
|
-
conditionMulti.push(getQueryMultiConditonItem(item, index))
|
|
216
|
-
})
|
|
217
|
-
this.$emit('update:visible', false)
|
|
218
|
-
this.$emit('change', { conditionAlways, conditionMulti })
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* 方案增改接口数据格式处理
|
|
223
|
-
* 新增和修改方案的接口数据格式一致,统一将页面数据格式化
|
|
224
|
-
*/
|
|
225
|
-
paramDataFormat (type, setDefault) {
|
|
226
|
-
// 处理方案信息
|
|
227
|
-
const planMsg = {
|
|
228
|
-
name: this.planContent.name,
|
|
229
|
-
isDefault: false
|
|
230
|
-
}
|
|
231
|
-
if (type === 'update') {
|
|
232
|
-
planMsg.id = this.planContent.id
|
|
233
|
-
planMsg.isDefault = typeof setDefault === 'undefined'
|
|
234
|
-
? this.planContent.isDefault
|
|
235
|
-
: setDefault
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// 处理常用条件的结果
|
|
239
|
-
const alwaysConditionData = []
|
|
240
|
-
for (const alwaysItem of this.planContent.schemeUsefulList) {
|
|
241
|
-
alwaysConditionData.push({
|
|
242
|
-
field: alwaysItem.field,
|
|
243
|
-
values: alwaysItem.values
|
|
244
|
-
})
|
|
245
|
-
}
|
|
246
|
-
// 添加高级过滤条件的sort属性
|
|
247
|
-
const multiConditionData = JSON.parse(JSON.stringify(this.planContent.contentsList))
|
|
248
|
-
multiConditionData.forEach((item, index) => {
|
|
249
|
-
item.sort = index
|
|
250
|
-
item.id = null
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
return {
|
|
254
|
-
planMsg,
|
|
255
|
-
conditionAlways: alwaysConditionData,
|
|
256
|
-
conditionMulti: multiConditionData
|
|
257
|
-
}
|
|
258
|
-
},
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* 保存按钮和设置为默认方案按钮的处理函数
|
|
262
|
-
* 方案的修改,和修改为默认方案
|
|
263
|
-
*/
|
|
264
|
-
async update (event, setDefault) {
|
|
265
|
-
if (this.planContent.id === '0') {
|
|
266
|
-
return this.$message.error('缺省方案不能被修改,可以尝试保存为新方案')
|
|
267
|
-
}
|
|
268
|
-
if (this.planNames.filter(name => name !== this.planContent.name).includes(this.planContent.name)) {
|
|
269
|
-
return this.$message.error('该名称已经被其他方案占用')
|
|
270
|
-
}
|
|
271
|
-
if (!this.conditionValidate()) {
|
|
272
|
-
return
|
|
273
|
-
}
|
|
274
|
-
const res = await updatePlan(this.target, this.paramDataFormat('update', setDefault))
|
|
275
|
-
if (res.code !== 0) {
|
|
276
|
-
return this.$message.error(res.msg)
|
|
277
|
-
}
|
|
278
|
-
this.$message.success('修改成功')
|
|
279
|
-
this.$emit('listChange', this.planContent.id)
|
|
280
|
-
},
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* 保存为新方案的按钮处理函数
|
|
284
|
-
* 添加一个新的方案
|
|
285
|
-
*/
|
|
286
|
-
async add () {
|
|
287
|
-
if (this.planNames.includes(this.planContent.name)) {
|
|
288
|
-
return this.$message.error('该方案名称已经存在')
|
|
289
|
-
}
|
|
290
|
-
if (!this.conditionValidate()) {
|
|
291
|
-
return
|
|
292
|
-
}
|
|
293
|
-
const res = await addPlan(this.target, this.paramDataFormat('insert'))
|
|
294
|
-
if (res.code !== 0) {
|
|
295
|
-
return this.$message.error(res.msg)
|
|
296
|
-
}
|
|
297
|
-
this.$message.success('保存成功')
|
|
298
|
-
this.$emit('listChange', res.data)
|
|
299
|
-
},
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* 删除当前方案
|
|
303
|
-
*/
|
|
304
|
-
async deletePlan () {
|
|
305
|
-
if (this.planContent.id === '0') {
|
|
306
|
-
return this.$message.error('缺省方案不允许删除')
|
|
307
|
-
}
|
|
308
|
-
const res = await deletePlan(this.target, this.planContent.id)
|
|
309
|
-
if (res.code !== 0) {
|
|
310
|
-
return this.$message.error(res.msg)
|
|
311
|
-
}
|
|
312
|
-
this.$message.success('删除成功')
|
|
313
|
-
this.$emit('listChange')
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
</script>
|
|
318
|
-
|
|
319
|
-
<style scoped lang='less'>
|
|
320
|
-
.title {
|
|
321
|
-
font-size:18px;
|
|
322
|
-
}
|
|
323
|
-
.plan-content {
|
|
324
|
-
position:absolute;
|
|
325
|
-
top:24px;
|
|
326
|
-
width:900px;
|
|
327
|
-
display:flex;
|
|
328
|
-
background-color: #fff;
|
|
329
|
-
z-index:9;
|
|
330
|
-
box-shadow: 5px 5px 10px 3px rgba(0, 0, 0, 0.2);
|
|
331
|
-
|
|
332
|
-
// 左侧的方案详情
|
|
333
|
-
.plan-details {
|
|
334
|
-
padding:20px;
|
|
335
|
-
flex:6;
|
|
336
|
-
// background-color: #f6f7f9;
|
|
337
|
-
background-color: #fff;
|
|
338
|
-
// .condition-always {
|
|
339
|
-
// margin-top:15px;
|
|
340
|
-
// }
|
|
341
|
-
|
|
342
|
-
.condition-always {
|
|
343
|
-
margin-top:30px;
|
|
344
|
-
/deep/.el-scrollbar{
|
|
345
|
-
height: 20vh;
|
|
346
|
-
.el-scrollbar__wrap{
|
|
347
|
-
overflow-x: hidden;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
.plan-conditions {
|
|
353
|
-
.add-button {
|
|
354
|
-
cursor:pointer;
|
|
355
|
-
user-select: none;
|
|
356
|
-
width:50px;
|
|
357
|
-
// border:1px solid black;
|
|
358
|
-
span {
|
|
359
|
-
margin-left:3px;
|
|
360
|
-
}
|
|
361
|
-
span:hover {
|
|
362
|
-
color:#0a5295;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// 右侧的操作按钮组
|
|
369
|
-
.plan-buttons {
|
|
370
|
-
border-left:1px solid #dddfe6;
|
|
371
|
-
flex:2;
|
|
372
|
-
|
|
373
|
-
.buttons{
|
|
374
|
-
height:300px;
|
|
375
|
-
display:flex;
|
|
376
|
-
flex-direction:column;
|
|
377
|
-
.el-button {
|
|
378
|
-
margin:10px 40px;
|
|
379
|
-
background-color: #055A9D;
|
|
380
|
-
border:none;
|
|
381
|
-
}
|
|
382
|
-
.is-disabled {
|
|
383
|
-
background-color: #357bc2;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div v-show="visible" v-clickoutside="handleClickOut" class="plan-content">
|
|
3
|
+
<!--
|
|
4
|
+
方案详情,包含名称,过滤条件
|
|
5
|
+
-->
|
|
6
|
+
<div class="plan-details">
|
|
7
|
+
<div class="plan-title">
|
|
8
|
+
<span class="title">方案名称:</span>
|
|
9
|
+
<el-input v-model="planContent.name" size="mini" />
|
|
10
|
+
<span class="error">{{ errorMsg }}</span>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<!-- 常用条件 -->
|
|
14
|
+
<div class="condition-always">
|
|
15
|
+
<span class="title">常用条件</span>
|
|
16
|
+
<el-scrollbar>
|
|
17
|
+
<ConditionAlwaysItem
|
|
18
|
+
v-for="item in planContent.schemeUsefulList"
|
|
19
|
+
:key="item.field"
|
|
20
|
+
v-model="item.values"
|
|
21
|
+
:data="item"
|
|
22
|
+
/>
|
|
23
|
+
</el-scrollbar>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<!--高级过滤条件 -->
|
|
27
|
+
<div class="plan-conditions">
|
|
28
|
+
<span class="title">高级查询</span>
|
|
29
|
+
<div>
|
|
30
|
+
<ConditionItem
|
|
31
|
+
v-for="condition in planContent.contentsList"
|
|
32
|
+
:key="condition.id"
|
|
33
|
+
:condition="condition"
|
|
34
|
+
@remove="removeCondition(condition)"
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="add-button" @click="addCondition">
|
|
39
|
+
<i class="el-icon-plus" />
|
|
40
|
+
<span>添加</span>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<!--
|
|
46
|
+
方案操作
|
|
47
|
+
-->
|
|
48
|
+
<div class="plan-buttons">
|
|
49
|
+
<div class="buttons">
|
|
50
|
+
<el-button type="primary" size="mini" @click="conditionChange">查询</el-button>
|
|
51
|
+
<el-button type="primary" size="mini" @click="update($event)">保存</el-button>
|
|
52
|
+
<el-button type="primary" size="mini" @click="add">保存为新方案</el-button>
|
|
53
|
+
<el-button type="primary" size="mini" :disabled="planContent.isDefault" @click="update($event,true)">保存为默认</el-button>
|
|
54
|
+
<el-button type="primary" size="mini" @click="deletePlan">删除方案</el-button>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
59
|
+
<script>
|
|
60
|
+
import { getAllOverOperatorList } from '../js/operatorEnum'
|
|
61
|
+
import Clickoutside from 'element-ui/src/utils/clickoutside'
|
|
62
|
+
import ConditionItem from './condition-mult-item.vue'
|
|
63
|
+
import ConditionAlwaysItem from './condition-always-item.vue'
|
|
64
|
+
import { addPlan, deletePlan, updatePlan } from '@/api/tableV3.js'
|
|
65
|
+
export default {
|
|
66
|
+
components: {
|
|
67
|
+
ConditionItem,
|
|
68
|
+
ConditionAlwaysItem
|
|
69
|
+
},
|
|
70
|
+
directives: { Clickoutside },
|
|
71
|
+
props: {
|
|
72
|
+
visible: {
|
|
73
|
+
type: Boolean,
|
|
74
|
+
default: false
|
|
75
|
+
},
|
|
76
|
+
// 方案详情的内容
|
|
77
|
+
content: {
|
|
78
|
+
type: Object,
|
|
79
|
+
default: null
|
|
80
|
+
},
|
|
81
|
+
// 当前所有方案的名称
|
|
82
|
+
planNames: {
|
|
83
|
+
type: Array,
|
|
84
|
+
default: null
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
data () {
|
|
88
|
+
return {
|
|
89
|
+
errorMsg: '',
|
|
90
|
+
planContent: {
|
|
91
|
+
name: '',
|
|
92
|
+
schemeUsefulList: [],
|
|
93
|
+
contentsList: []
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
inject: ['target'],
|
|
98
|
+
watch: {
|
|
99
|
+
content (newValue) {
|
|
100
|
+
this.loadPlanContent(newValue)
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
methods: {
|
|
104
|
+
// 加载一个方案数据,处理方案的数据,并发射条件变更事件
|
|
105
|
+
loadPlanContent (content, immediate = false) {
|
|
106
|
+
const contentCopy = JSON.parse(JSON.stringify(content))
|
|
107
|
+
contentCopy.contentsList = contentCopy.contentsList || []
|
|
108
|
+
for (const alwaysItem of contentCopy.schemeUsefulList) {
|
|
109
|
+
if (!alwaysItem.values.length) {
|
|
110
|
+
alwaysItem.values.push('-1')
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
this.planContent = contentCopy
|
|
114
|
+
this.conditionChange()
|
|
115
|
+
},
|
|
116
|
+
// 点击方案内容外侧收起方案详情弹窗
|
|
117
|
+
handleClickOut () {
|
|
118
|
+
if (!this.visible) return
|
|
119
|
+
this.$emit('update:visible', false)
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
* 添加一个高级过滤条件
|
|
123
|
+
*/
|
|
124
|
+
addCondition () {
|
|
125
|
+
const conditionModel = {
|
|
126
|
+
id: Math.random().toString(36).slice(8),
|
|
127
|
+
leftBracket: '(',
|
|
128
|
+
field: '',
|
|
129
|
+
operator: '',
|
|
130
|
+
value: '',
|
|
131
|
+
rightBracket: ')',
|
|
132
|
+
relation: 'AND',
|
|
133
|
+
fieldType: '',
|
|
134
|
+
userSchemeId: this.content.id
|
|
135
|
+
}
|
|
136
|
+
this.planContent.contentsList.push(conditionModel)
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 删除一个高级过滤条件
|
|
141
|
+
*/
|
|
142
|
+
removeCondition (condition) {
|
|
143
|
+
const index = this.planContent.contentsList.indexOf(condition)
|
|
144
|
+
this.planContent.contentsList.splice(index, 1)
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* 条件前端校验
|
|
149
|
+
* 校验含有空值,以及括号是否闭合
|
|
150
|
+
*/
|
|
151
|
+
conditionValidate () {
|
|
152
|
+
const bracketStack = []
|
|
153
|
+
for (const condition of this.planContent.contentsList) {
|
|
154
|
+
if (!getAllOverOperatorList().includes(condition.operator) && !condition.value) {
|
|
155
|
+
this.$message.error('方案中存在没有填写内容的条件')
|
|
156
|
+
return false
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
bracketStack.push(...condition.leftBracket.split(''))
|
|
160
|
+
for (let i = 0; i < condition.rightBracket.length; i++) {
|
|
161
|
+
if (!bracketStack.pop()) {
|
|
162
|
+
this.$message.error('方案中条件的括号没有闭合')
|
|
163
|
+
return false
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (bracketStack.length) {
|
|
169
|
+
this.$message.error('方案中条件的括号没有闭合')
|
|
170
|
+
return false
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return true
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 搜索按钮的处理函数
|
|
178
|
+
* 条件已经变更,将变更后的条件发射出去,父组件接受处理后使用新的条件调用接口查询数据
|
|
179
|
+
*/
|
|
180
|
+
conditionChange () {
|
|
181
|
+
if (!this.conditionValidate()) {
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// 常用条件格式化
|
|
186
|
+
const conditionAlways = []
|
|
187
|
+
for (const conditionAlwaysItem of this.planContent.schemeUsefulList) {
|
|
188
|
+
conditionAlways.push({
|
|
189
|
+
field: conditionAlwaysItem.field,
|
|
190
|
+
values: conditionAlwaysItem.values
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// 高级过滤条件格式化
|
|
195
|
+
const conditionMulti = []
|
|
196
|
+
const getQueryMultiConditonItem = function (sourceMultiItem, index) {
|
|
197
|
+
const keys = [
|
|
198
|
+
'leftBracket',
|
|
199
|
+
'field',
|
|
200
|
+
'operator',
|
|
201
|
+
'value',
|
|
202
|
+
'rightBracket',
|
|
203
|
+
'relation',
|
|
204
|
+
'fieldType'
|
|
205
|
+
]
|
|
206
|
+
const res = {}
|
|
207
|
+
res.sort = index
|
|
208
|
+
for (const key of keys) {
|
|
209
|
+
res[key] = sourceMultiItem[key]
|
|
210
|
+
}
|
|
211
|
+
return res
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
this.planContent.contentsList.forEach((item, index) => {
|
|
215
|
+
conditionMulti.push(getQueryMultiConditonItem(item, index))
|
|
216
|
+
})
|
|
217
|
+
this.$emit('update:visible', false)
|
|
218
|
+
this.$emit('change', { conditionAlways, conditionMulti })
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* 方案增改接口数据格式处理
|
|
223
|
+
* 新增和修改方案的接口数据格式一致,统一将页面数据格式化
|
|
224
|
+
*/
|
|
225
|
+
paramDataFormat (type, setDefault) {
|
|
226
|
+
// 处理方案信息
|
|
227
|
+
const planMsg = {
|
|
228
|
+
name: this.planContent.name,
|
|
229
|
+
isDefault: false
|
|
230
|
+
}
|
|
231
|
+
if (type === 'update') {
|
|
232
|
+
planMsg.id = this.planContent.id
|
|
233
|
+
planMsg.isDefault = typeof setDefault === 'undefined'
|
|
234
|
+
? this.planContent.isDefault
|
|
235
|
+
: setDefault
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// 处理常用条件的结果
|
|
239
|
+
const alwaysConditionData = []
|
|
240
|
+
for (const alwaysItem of this.planContent.schemeUsefulList) {
|
|
241
|
+
alwaysConditionData.push({
|
|
242
|
+
field: alwaysItem.field,
|
|
243
|
+
values: alwaysItem.values
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
// 添加高级过滤条件的sort属性
|
|
247
|
+
const multiConditionData = JSON.parse(JSON.stringify(this.planContent.contentsList))
|
|
248
|
+
multiConditionData.forEach((item, index) => {
|
|
249
|
+
item.sort = index
|
|
250
|
+
item.id = null
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
planMsg,
|
|
255
|
+
conditionAlways: alwaysConditionData,
|
|
256
|
+
conditionMulti: multiConditionData
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* 保存按钮和设置为默认方案按钮的处理函数
|
|
262
|
+
* 方案的修改,和修改为默认方案
|
|
263
|
+
*/
|
|
264
|
+
async update (event, setDefault) {
|
|
265
|
+
if (this.planContent.id === '0') {
|
|
266
|
+
return this.$message.error('缺省方案不能被修改,可以尝试保存为新方案')
|
|
267
|
+
}
|
|
268
|
+
if (this.planNames.filter(name => name !== this.planContent.name).includes(this.planContent.name)) {
|
|
269
|
+
return this.$message.error('该名称已经被其他方案占用')
|
|
270
|
+
}
|
|
271
|
+
if (!this.conditionValidate()) {
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
const res = await updatePlan(this.target, this.paramDataFormat('update', setDefault))
|
|
275
|
+
if (res.code !== 0) {
|
|
276
|
+
return this.$message.error(res.msg)
|
|
277
|
+
}
|
|
278
|
+
this.$message.success('修改成功')
|
|
279
|
+
this.$emit('listChange', this.planContent.id)
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* 保存为新方案的按钮处理函数
|
|
284
|
+
* 添加一个新的方案
|
|
285
|
+
*/
|
|
286
|
+
async add () {
|
|
287
|
+
if (this.planNames.includes(this.planContent.name)) {
|
|
288
|
+
return this.$message.error('该方案名称已经存在')
|
|
289
|
+
}
|
|
290
|
+
if (!this.conditionValidate()) {
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
const res = await addPlan(this.target, this.paramDataFormat('insert'))
|
|
294
|
+
if (res.code !== 0) {
|
|
295
|
+
return this.$message.error(res.msg)
|
|
296
|
+
}
|
|
297
|
+
this.$message.success('保存成功')
|
|
298
|
+
this.$emit('listChange', res.data)
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* 删除当前方案
|
|
303
|
+
*/
|
|
304
|
+
async deletePlan () {
|
|
305
|
+
if (this.planContent.id === '0') {
|
|
306
|
+
return this.$message.error('缺省方案不允许删除')
|
|
307
|
+
}
|
|
308
|
+
const res = await deletePlan(this.target, this.planContent.id)
|
|
309
|
+
if (res.code !== 0) {
|
|
310
|
+
return this.$message.error(res.msg)
|
|
311
|
+
}
|
|
312
|
+
this.$message.success('删除成功')
|
|
313
|
+
this.$emit('listChange')
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
</script>
|
|
318
|
+
|
|
319
|
+
<style scoped lang='less'>
|
|
320
|
+
.title {
|
|
321
|
+
font-size:18px;
|
|
322
|
+
}
|
|
323
|
+
.plan-content {
|
|
324
|
+
position:absolute;
|
|
325
|
+
top:24px;
|
|
326
|
+
width:900px;
|
|
327
|
+
display:flex;
|
|
328
|
+
background-color: #fff;
|
|
329
|
+
z-index:9;
|
|
330
|
+
box-shadow: 5px 5px 10px 3px rgba(0, 0, 0, 0.2);
|
|
331
|
+
|
|
332
|
+
// 左侧的方案详情
|
|
333
|
+
.plan-details {
|
|
334
|
+
padding:20px;
|
|
335
|
+
flex:6;
|
|
336
|
+
// background-color: #f6f7f9;
|
|
337
|
+
background-color: #fff;
|
|
338
|
+
// .condition-always {
|
|
339
|
+
// margin-top:15px;
|
|
340
|
+
// }
|
|
341
|
+
|
|
342
|
+
.condition-always {
|
|
343
|
+
margin-top:30px;
|
|
344
|
+
/deep/.el-scrollbar{
|
|
345
|
+
height: 20vh;
|
|
346
|
+
.el-scrollbar__wrap{
|
|
347
|
+
overflow-x: hidden;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.plan-conditions {
|
|
353
|
+
.add-button {
|
|
354
|
+
cursor:pointer;
|
|
355
|
+
user-select: none;
|
|
356
|
+
width:50px;
|
|
357
|
+
// border:1px solid black;
|
|
358
|
+
span {
|
|
359
|
+
margin-left:3px;
|
|
360
|
+
}
|
|
361
|
+
span:hover {
|
|
362
|
+
color:#0a5295;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// 右侧的操作按钮组
|
|
369
|
+
.plan-buttons {
|
|
370
|
+
border-left:1px solid #dddfe6;
|
|
371
|
+
flex:2;
|
|
372
|
+
|
|
373
|
+
.buttons{
|
|
374
|
+
height:300px;
|
|
375
|
+
display:flex;
|
|
376
|
+
flex-direction:column;
|
|
377
|
+
.el-button {
|
|
378
|
+
margin:10px 40px;
|
|
379
|
+
background-color: #055A9D;
|
|
380
|
+
border:none;
|
|
381
|
+
}
|
|
382
|
+
.is-disabled {
|
|
383
|
+
background-color: #357bc2;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
</style>
|