@netang/quasar 0.0.22 → 0.0.24
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/components/dialog/index.vue +1 -3
- package/components/field-date/index.vue +2 -21
- package/components/field-table/index.vue +623 -214
- package/components/field-tree/index.vue +2 -30
- package/components/search/index.vue +95 -93
- package/components/table/index.vue +33 -26
- package/components/table-pagination/index.vue +35 -5
- package/package.json +1 -1
- package/sass/quasar/field.scss +9 -8
- package/utils/$power.js +18 -8
- package/utils/$table.js +304 -172
- package/utils/$tree.js +1 -1
|
@@ -1,54 +1,89 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<!--:class="fieldFocused ? 'q-field--float q-field--focused q-field--highlighted' : ''"-->
|
|
2
3
|
<q-field
|
|
3
|
-
|
|
4
|
+
class="n-field-table"
|
|
4
5
|
:model-value="modelValue"
|
|
5
6
|
:readonly="readonly"
|
|
6
|
-
|
|
7
|
+
:clearable="clearable && ! multiple"
|
|
8
|
+
@clear="onFieldClear"
|
|
7
9
|
v-bind="$attrs"
|
|
8
10
|
>
|
|
9
11
|
<template v-slot:control>
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
<template v-if="multiple">
|
|
14
|
+
|
|
15
|
+
<!-- 多选插槽 -->
|
|
16
|
+
<slot
|
|
17
|
+
name="selected"
|
|
18
|
+
:selected="selected"
|
|
19
|
+
:remove="onRemoveSelected"
|
|
20
|
+
v-if="$slots.selected"
|
|
21
|
+
/>
|
|
22
|
+
|
|
23
|
+
<!-- 多选标签 -->
|
|
24
|
+
<template v-else>
|
|
25
|
+
<q-chip
|
|
26
|
+
v-for="(item, index) in selected"
|
|
27
|
+
:key="`options-${index}`"
|
|
28
|
+
:label="item[labelKey || rowKey]"
|
|
29
|
+
removable
|
|
30
|
+
@remove="onRemoveSelected(item, index)"
|
|
31
|
+
dense
|
|
32
|
+
/>
|
|
33
|
+
</template>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<!-- 显示文字 -->
|
|
37
|
+
<span v-else>
|
|
38
|
+
{{showValue}}
|
|
39
|
+
</span>
|
|
40
|
+
|
|
41
|
+
<!-- 筛选输入框 -->
|
|
42
|
+
<input
|
|
43
|
+
ref="inputRef"
|
|
44
|
+
class="q-field__input q-placeholder col q-field__input--padding"
|
|
45
|
+
v-model="inputValue"
|
|
46
|
+
v-if="filter"
|
|
47
|
+
/>
|
|
13
48
|
|
|
14
|
-
<!--<!– 显示占位符 –>-->
|
|
15
|
-
<!--<div class="n-placeholder" v-else-if="placeholder">{{placeholder}}</div>-->
|
|
16
49
|
</template>
|
|
17
50
|
|
|
18
|
-
|
|
51
|
+
<!-- 弹出对话框图标 -->
|
|
52
|
+
<template v-slot:append v-if="! noDialog">
|
|
19
53
|
<q-icon
|
|
20
54
|
class="cursor-pointer"
|
|
21
55
|
name="search"
|
|
22
|
-
@click.prevent.stop="
|
|
56
|
+
@click.prevent.stop="showDialog = true"
|
|
23
57
|
/>
|
|
24
58
|
</template>
|
|
25
59
|
|
|
60
|
+
<!-- 弹出层代理 -->
|
|
26
61
|
<q-popup-proxy
|
|
27
62
|
ref="popupRef"
|
|
28
|
-
|
|
63
|
+
no-refocus
|
|
64
|
+
no-focus
|
|
29
65
|
@show="onPopupShow"
|
|
30
|
-
@
|
|
31
|
-
@hide="onPopupHide"
|
|
66
|
+
@focus="onPopupFocus"
|
|
32
67
|
v-if="! readonly"
|
|
33
68
|
>
|
|
69
|
+
<!-- 快捷表格 -->
|
|
34
70
|
<q-table
|
|
35
|
-
ref="tableRef"
|
|
36
71
|
class="n-table"
|
|
37
72
|
style="min-width:500px;max-width:90vw;height: 300px;"
|
|
38
73
|
v-model:pagination="tablePagination"
|
|
39
|
-
v-model:selected="
|
|
74
|
+
v-model:selected="selected"
|
|
40
75
|
:row-key="tableRowKey"
|
|
41
76
|
:rows="tableRows"
|
|
42
|
-
:columns="
|
|
43
|
-
:selection="
|
|
77
|
+
:columns="columns"
|
|
78
|
+
:selection="multiple ? 'multiple' : 'none'"
|
|
44
79
|
:loading="tableLoading"
|
|
45
80
|
:rows-per-page-options="tableRowsPerPageOptions"
|
|
46
|
-
@row-click="
|
|
47
|
-
@row-dblclick="tableRowDblclick"
|
|
81
|
+
@row-click="quickTableRowClick"
|
|
48
82
|
@request="tableRequest"
|
|
49
83
|
flat
|
|
50
84
|
virtual-scroll
|
|
51
85
|
dense
|
|
86
|
+
v-bind="tableProps"
|
|
52
87
|
>
|
|
53
88
|
<!-- 图片 -->
|
|
54
89
|
<template
|
|
@@ -77,42 +112,37 @@
|
|
|
77
112
|
</q-td>
|
|
78
113
|
</template>
|
|
79
114
|
|
|
80
|
-
<!-- 合计 -->
|
|
81
|
-
<!--<template v-slot:bottom-row="props" v-if="tableSummary">-->
|
|
82
|
-
<!-- <n-table-summary-->
|
|
83
|
-
<!-- :props="props"-->
|
|
84
|
-
<!-- :data="tableSummary"-->
|
|
85
|
-
<!-- :selection="tableSelection"-->
|
|
86
|
-
<!-- />-->
|
|
87
|
-
<!--</template>-->
|
|
88
|
-
|
|
89
115
|
<!-- 翻页 -->
|
|
90
116
|
<template v-slot:pagination="props">
|
|
91
117
|
<n-table-pagination
|
|
92
118
|
:props="props"
|
|
93
|
-
|
|
119
|
+
no-power
|
|
120
|
+
dense
|
|
94
121
|
/>
|
|
95
122
|
</template>
|
|
96
123
|
</q-table>
|
|
97
124
|
</q-popup-proxy>
|
|
98
125
|
</q-field>
|
|
99
126
|
|
|
127
|
+
<!-- 弹出对话框 -->
|
|
100
128
|
<n-dialog
|
|
101
|
-
title="选择商品"
|
|
102
129
|
v-model="showDialog"
|
|
130
|
+
width="80%"
|
|
131
|
+
:on-confirm="onDialogConfirm"
|
|
132
|
+
@before-show="onDialogBeforeShow"
|
|
133
|
+
@show="onDialogShow"
|
|
134
|
+
@hide="onDialogHide"
|
|
135
|
+
cancel
|
|
136
|
+
v-bind="dialogProps"
|
|
103
137
|
>
|
|
104
138
|
<q-page>
|
|
105
|
-
<n-table
|
|
106
|
-
page-status
|
|
107
|
-
@load="onPopupShow"
|
|
108
|
-
/>
|
|
139
|
+
<n-table />
|
|
109
140
|
</q-page>
|
|
110
141
|
</n-dialog>
|
|
111
142
|
</template>
|
|
112
143
|
|
|
113
144
|
<script>
|
|
114
|
-
import { ref,
|
|
115
|
-
import { NFieldTableKey } from '../../utils/symbols'
|
|
145
|
+
import { ref, computed, watch, onMounted } from 'vue'
|
|
116
146
|
|
|
117
147
|
export default {
|
|
118
148
|
|
|
@@ -126,40 +156,70 @@ export default {
|
|
|
126
156
|
*/
|
|
127
157
|
props: {
|
|
128
158
|
// 值
|
|
129
|
-
modelValue: [String, Number],
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
159
|
+
modelValue: [ String, Number, Array ],
|
|
160
|
+
// 是否可清除
|
|
161
|
+
clearable: Boolean,
|
|
162
|
+
// 表格请求路径
|
|
163
|
+
path: String,
|
|
164
|
+
// 表格请求参数
|
|
165
|
+
query: Object,
|
|
166
|
+
// 附加请求数据
|
|
167
|
+
data: Object,
|
|
168
|
+
// 已选数据
|
|
169
|
+
selected: Array,
|
|
170
|
+
// 初始加载选择数据
|
|
171
|
+
loadSelected: {
|
|
172
|
+
type: Boolean,
|
|
173
|
+
default: true,
|
|
174
|
+
},
|
|
175
|
+
// 值字段(必填)
|
|
140
176
|
valueKey: {
|
|
141
177
|
type: String,
|
|
142
178
|
required: true,
|
|
143
179
|
},
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
type:
|
|
180
|
+
// 标签字段(必填)
|
|
181
|
+
labelKey: {
|
|
182
|
+
type: String,
|
|
147
183
|
required: true,
|
|
148
184
|
},
|
|
149
|
-
// 默认搜索属性名称
|
|
150
|
-
searchKey: String,
|
|
151
|
-
|
|
152
|
-
// 表格列数据
|
|
153
|
-
columns: Array,
|
|
154
185
|
// 表格行唯一键值
|
|
155
186
|
rowKey: {
|
|
156
187
|
type: String,
|
|
157
188
|
default: 'id',
|
|
158
189
|
},
|
|
159
|
-
//
|
|
160
|
-
|
|
190
|
+
// 快捷表格显示的字段数组(空为:[值字段, 标签字段])
|
|
191
|
+
showKeys: Array,
|
|
192
|
+
// 隐藏搜索字段数组
|
|
193
|
+
hideSearchKeys: Array,
|
|
194
|
+
// 默认筛选字段(空为:标签字段)
|
|
195
|
+
filterKey: String,
|
|
196
|
+
// 是否开启筛选
|
|
197
|
+
filter: Boolean,
|
|
198
|
+
// 表格声明属性
|
|
199
|
+
tableProps: Object,
|
|
200
|
+
// 对话框声明属性
|
|
201
|
+
dialogProps: Object,
|
|
202
|
+
|
|
203
|
+
// 占位符
|
|
204
|
+
placeholder: String,
|
|
205
|
+
// 是否只读
|
|
206
|
+
readonly: Boolean,
|
|
207
|
+
// 值是否为数组
|
|
208
|
+
valueArray: Boolean,
|
|
209
|
+
// 关闭对话框
|
|
210
|
+
noDialog: Boolean,
|
|
211
|
+
|
|
212
|
+
// 表格列数据
|
|
213
|
+
columns: Array,
|
|
161
214
|
// 行数据
|
|
162
215
|
rows: Array,
|
|
216
|
+
// 是否多选
|
|
217
|
+
multiple: Boolean,
|
|
218
|
+
// 输入防抖(毫秒)
|
|
219
|
+
inputDebounce: {
|
|
220
|
+
type: [ Number, String ],
|
|
221
|
+
default: 500
|
|
222
|
+
},
|
|
163
223
|
},
|
|
164
224
|
|
|
165
225
|
/**
|
|
@@ -167,6 +227,7 @@ export default {
|
|
|
167
227
|
*/
|
|
168
228
|
emits: [
|
|
169
229
|
'update:modelValue',
|
|
230
|
+
'update:selected',
|
|
170
231
|
],
|
|
171
232
|
|
|
172
233
|
/**
|
|
@@ -174,156 +235,427 @@ export default {
|
|
|
174
235
|
*/
|
|
175
236
|
setup(props, { emit, slots }) {
|
|
176
237
|
|
|
238
|
+
// ==========【计算属性】=========================================================================================
|
|
177
239
|
|
|
178
|
-
|
|
240
|
+
/**
|
|
241
|
+
* 插槽标识
|
|
242
|
+
*/
|
|
243
|
+
const slotNames = computed(function() {
|
|
244
|
+
return utils.isValidObject(slots) ? Object.keys(slots) : []
|
|
245
|
+
})
|
|
179
246
|
|
|
180
|
-
|
|
181
|
-
|
|
247
|
+
/**
|
|
248
|
+
* 当前显示字段
|
|
249
|
+
*/
|
|
250
|
+
const currentShowKeys = computed(function() {
|
|
251
|
+
return utils.isValidArray(props.showKeys)
|
|
252
|
+
? props.showKeys
|
|
253
|
+
: [ props.rowKey, props.labelKey ]
|
|
254
|
+
})
|
|
182
255
|
|
|
183
|
-
|
|
184
|
-
|
|
256
|
+
/**
|
|
257
|
+
* 当前搜索字段
|
|
258
|
+
*/
|
|
259
|
+
const currentFilterKeys = computed(function() {
|
|
260
|
+
return props.filterKey || props.labelKey
|
|
261
|
+
})
|
|
185
262
|
|
|
186
|
-
|
|
187
|
-
|
|
263
|
+
/**
|
|
264
|
+
* 显示值
|
|
265
|
+
*/
|
|
266
|
+
const showValue = computed(function () {
|
|
267
|
+
|
|
268
|
+
// 如果是单选
|
|
269
|
+
if (! props.multiple && utils.isValidArray(selected.value)) {
|
|
270
|
+
return selected.value[0][props.labelKey || props.rowKey]
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return ''
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
// ==========【数据】============================================================================================
|
|
188
277
|
|
|
189
|
-
//
|
|
190
|
-
|
|
278
|
+
// 创建权限实例
|
|
279
|
+
const $power = utils.$power.create({
|
|
280
|
+
// 路由路径
|
|
281
|
+
path: utils.isValidString(props.path) ? props.path : false,
|
|
282
|
+
// 路由参数
|
|
283
|
+
query: props.query,
|
|
284
|
+
// 关闭权限页面
|
|
285
|
+
power: false,
|
|
286
|
+
})
|
|
191
287
|
|
|
192
|
-
|
|
288
|
+
const {
|
|
289
|
+
// 当前路由路径
|
|
290
|
+
routePath,
|
|
291
|
+
} = $power
|
|
292
|
+
|
|
293
|
+
// 创建表格实例
|
|
193
294
|
const $table = utils.$table.create({
|
|
194
|
-
|
|
295
|
+
// 权限实例
|
|
296
|
+
$power,
|
|
297
|
+
// 附加请求数据
|
|
298
|
+
data: props.data,
|
|
195
299
|
// 获取表格列数据
|
|
196
300
|
columns: getTableColumns(),
|
|
197
301
|
// 表格行唯一键值
|
|
198
302
|
rowKey: props.rowKey,
|
|
303
|
+
// 行数据
|
|
304
|
+
rows: props.rows,
|
|
199
305
|
// 选择类型, 可选值 single multiple none
|
|
200
|
-
selection: props.multiple ? 'multiple' : '
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
|
|
306
|
+
selection: props.multiple ? 'multiple' : 'single',
|
|
307
|
+
// 已选数据
|
|
308
|
+
selected: props.selected,
|
|
309
|
+
// http 设置
|
|
310
|
+
httpSettings: {
|
|
311
|
+
// 头部请求
|
|
312
|
+
headers: {
|
|
313
|
+
// 添加头部查看请求
|
|
314
|
+
Pview: 1,
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
// 刷新后清空已选数据
|
|
318
|
+
refreshResetSelected: false,
|
|
205
319
|
})
|
|
206
320
|
|
|
207
|
-
//
|
|
321
|
+
// 创建防抖睡眠方法
|
|
322
|
+
const sleep = utils.debounceSleep()
|
|
208
323
|
|
|
209
|
-
//
|
|
210
|
-
|
|
211
|
-
// 表格实例
|
|
212
|
-
$table,
|
|
213
|
-
})
|
|
324
|
+
// 输入框节点
|
|
325
|
+
const inputRef = ref(null)
|
|
214
326
|
|
|
215
|
-
//
|
|
327
|
+
// 输入框值
|
|
328
|
+
const inputValue = ref('')
|
|
329
|
+
|
|
330
|
+
// 弹出层节点
|
|
331
|
+
const popupRef = ref(null)
|
|
332
|
+
|
|
333
|
+
// 是否显示对话框
|
|
334
|
+
const showDialog = ref(false)
|
|
335
|
+
|
|
336
|
+
// 当前已选数据
|
|
337
|
+
const selected = ref([...$table.tableSelected.value])
|
|
338
|
+
|
|
339
|
+
// 当前表格列数据
|
|
340
|
+
const columns = getQuickTableColumns()
|
|
341
|
+
|
|
342
|
+
// 如果有已选数据
|
|
343
|
+
if (utils.isValidArray(selected.value)) {
|
|
344
|
+
// 检查值更新
|
|
345
|
+
checkModelValueChange()
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// ==========【监听数据】=========================================================================================
|
|
216
349
|
|
|
217
350
|
/**
|
|
218
|
-
*
|
|
351
|
+
* 监听声明值
|
|
219
352
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
353
|
+
watch(()=>props.modelValue, async function() {
|
|
354
|
+
|
|
355
|
+
// 格式化值
|
|
356
|
+
let values = formatModelValue()
|
|
357
|
+
|
|
358
|
+
// 如果值不是有效数组
|
|
359
|
+
if (! utils.isValidArray(values)) {
|
|
360
|
+
// 则清空已选数据
|
|
361
|
+
selected.value = []
|
|
362
|
+
return
|
|
363
|
+
}
|
|
364
|
+
values = _.uniq(values)
|
|
365
|
+
|
|
366
|
+
// 已选数据值数组
|
|
367
|
+
const selectedValues = utils.isValidArray(selected.value)
|
|
368
|
+
// 如果有已选数据
|
|
369
|
+
? _.uniq(selected.value.map(e => e[props.rowKey]))
|
|
370
|
+
// 否则为空
|
|
371
|
+
: []
|
|
372
|
+
|
|
373
|
+
// 需增删除的值
|
|
374
|
+
const removeValues = selectedValues.filter(e => values.indexOf(e) === -1)
|
|
375
|
+
if (removeValues.length) {
|
|
376
|
+
utils.forEachRight(selected.value, function (item, index) {
|
|
377
|
+
if (removeValues.indexOf(item[props.rowKey]) > -1) {
|
|
378
|
+
selected.value.splice(index, 1)
|
|
379
|
+
}
|
|
380
|
+
})
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// 需增加的值
|
|
384
|
+
const addValues = values.filter(e => selectedValues.indexOf(e) === -1)
|
|
385
|
+
if (addValues.length) {
|
|
386
|
+
// 请求选择数据
|
|
387
|
+
selected.value.push(...await onRequestSelected(addValues))
|
|
223
388
|
}
|
|
224
|
-
return []
|
|
225
389
|
})
|
|
226
390
|
|
|
227
391
|
/**
|
|
228
|
-
*
|
|
392
|
+
* 监听声明选择数据
|
|
229
393
|
*/
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
// : props.columns
|
|
238
|
-
//
|
|
239
|
-
// // 如果有原始表格列数据
|
|
240
|
-
// return utils.isValidArray(rawTableColumns)
|
|
241
|
-
// // 克隆原始表格列数据
|
|
242
|
-
// ? _.cloneDeep(rawTableColumns)
|
|
243
|
-
// : []
|
|
244
|
-
// })
|
|
394
|
+
watch(()=>props.selected, function(val) {
|
|
395
|
+
if (val !== selected.value) {
|
|
396
|
+
// 设置选择数据
|
|
397
|
+
selected.value = val
|
|
398
|
+
}
|
|
399
|
+
// 检查值更新
|
|
400
|
+
checkModelValueChange()
|
|
245
401
|
|
|
246
|
-
|
|
402
|
+
// 设置输入框焦点
|
|
403
|
+
setInputFocus()
|
|
404
|
+
|
|
405
|
+
}, {
|
|
406
|
+
// 深度监听
|
|
407
|
+
deep: true
|
|
408
|
+
})
|
|
247
409
|
|
|
248
410
|
/**
|
|
249
|
-
*
|
|
411
|
+
* 监听当前已选数据
|
|
250
412
|
*/
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
413
|
+
watch(selected, function(val) {
|
|
414
|
+
if (val !== props.selected) {
|
|
415
|
+
emit('update:selected', val)
|
|
416
|
+
}
|
|
417
|
+
}, {
|
|
418
|
+
// 深度监听
|
|
419
|
+
deep: true,
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* 监听输入框值
|
|
424
|
+
*/
|
|
425
|
+
watch(inputValue, async function (val) {
|
|
426
|
+
|
|
427
|
+
// 取消延迟执行
|
|
428
|
+
sleep.cancel()
|
|
429
|
+
|
|
430
|
+
if (utils.isValidValue(val)) {
|
|
431
|
+
|
|
432
|
+
const n_search = {}
|
|
433
|
+
n_search[currentFilterKeys.value] = [
|
|
434
|
+
{
|
|
435
|
+
// 比较类型
|
|
436
|
+
type: dicts.SEARCH_TYPE__LIKE,
|
|
437
|
+
// 值
|
|
438
|
+
value: val || '',
|
|
439
|
+
}
|
|
440
|
+
]
|
|
441
|
+
|
|
442
|
+
$table.tableQuery.value = {
|
|
443
|
+
n_search,
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
} else {
|
|
447
|
+
$table.tableQuery.value = {}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// 延迟执行
|
|
451
|
+
await sleep(props.inputDebounce)
|
|
452
|
+
|
|
453
|
+
// 表格重新加载
|
|
454
|
+
await $table.tableReload()
|
|
455
|
+
})
|
|
254
456
|
|
|
255
457
|
// ==========【方法】=============================================================================================
|
|
256
458
|
|
|
459
|
+
/**
|
|
460
|
+
* 格式化值
|
|
461
|
+
*/
|
|
462
|
+
function formatModelValue() {
|
|
463
|
+
|
|
464
|
+
// 如果值是数组
|
|
465
|
+
if (props.valueArray) {
|
|
466
|
+
return props.modelValue
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// 否则值是字符串/数字
|
|
470
|
+
return utils.split(props.modelValue, ',')
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* 请求选择数据
|
|
475
|
+
*/
|
|
476
|
+
async function onRequestSelected(value) {
|
|
477
|
+
|
|
478
|
+
// 请求数据
|
|
479
|
+
const { status, data } = await utils.http({
|
|
480
|
+
url: $table.routePath,
|
|
481
|
+
data: Object.assign(
|
|
482
|
+
// 获取表格请求数据
|
|
483
|
+
$table.getTableRequestData({
|
|
484
|
+
// filter,
|
|
485
|
+
pagination: {
|
|
486
|
+
// 页码
|
|
487
|
+
page: 1,
|
|
488
|
+
// 每页的数据条数
|
|
489
|
+
rowsPerPage: value.length,
|
|
490
|
+
// 排序字段
|
|
491
|
+
sortBy: null,
|
|
492
|
+
// 是否降序排列
|
|
493
|
+
descending: true,
|
|
494
|
+
}
|
|
495
|
+
}, false),
|
|
496
|
+
{
|
|
497
|
+
// 查看字段
|
|
498
|
+
n_view: {
|
|
499
|
+
// 查看字段
|
|
500
|
+
field: props.rowKey,
|
|
501
|
+
// 查看值
|
|
502
|
+
value,
|
|
503
|
+
},
|
|
504
|
+
}
|
|
505
|
+
),
|
|
506
|
+
})
|
|
507
|
+
|
|
508
|
+
return status && utils.isValidArray(_.get(data, 'rows')) ? data.rows : []
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* 初始加载选择数据
|
|
513
|
+
*/
|
|
514
|
+
async function onLoadSelected() {
|
|
515
|
+
|
|
516
|
+
if (
|
|
517
|
+
// 如果初始不加载选择数据
|
|
518
|
+
! props.loadSelected
|
|
519
|
+
// 如果没有请求路由路径
|
|
520
|
+
|| ! routePath
|
|
521
|
+
// 如果有选择数据
|
|
522
|
+
|| utils.isValidArray(selected.value)
|
|
523
|
+
) {
|
|
524
|
+
// 则无任何操作
|
|
525
|
+
return
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// 格式化值
|
|
529
|
+
const value = formatModelValue()
|
|
530
|
+
|
|
531
|
+
// 如果值不是有效数组
|
|
532
|
+
if (! utils.isValidArray(value)) {
|
|
533
|
+
// 则无任何操作
|
|
534
|
+
return
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// 设置已选数据
|
|
538
|
+
selected.value = await onRequestSelected(value)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* 检查值更新
|
|
543
|
+
*/
|
|
544
|
+
function checkModelValueChange() {
|
|
545
|
+
|
|
546
|
+
let newModelValue = utils.isValidArray(selected.value)
|
|
547
|
+
// 如果有已选数据
|
|
548
|
+
? (
|
|
549
|
+
props.multiple
|
|
550
|
+
// 如果是多选
|
|
551
|
+
? selected.value.map(e => e[props.rowKey])
|
|
552
|
+
// 否则是单选
|
|
553
|
+
: [ selected.value[0][props.rowKey] ]
|
|
554
|
+
)
|
|
555
|
+
// 否则为空
|
|
556
|
+
: []
|
|
557
|
+
|
|
558
|
+
// 如果值为字符串或数字
|
|
559
|
+
if (! props.valueArray) {
|
|
560
|
+
newModelValue = utils.numberDeep(utils.join(newModelValue, ','))
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// 如果值发生改变
|
|
564
|
+
if (! _.isEqual(newModelValue, props.modelValue)) {
|
|
565
|
+
|
|
566
|
+
// 提交更新值
|
|
567
|
+
emit('update:modelValue', newModelValue)
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
257
571
|
/**
|
|
258
572
|
* 获取表格列数据
|
|
259
573
|
*/
|
|
260
574
|
function getTableColumns() {
|
|
261
575
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
576
|
+
let columns
|
|
577
|
+
|
|
578
|
+
// 如果有声明路由表格列数据
|
|
579
|
+
if (utils.isValidArray(props.columns)) {
|
|
580
|
+
columns = _.cloneDeep(props.columns)
|
|
581
|
+
|
|
582
|
+
// 如果有路由路径
|
|
583
|
+
} else if (routePath) {
|
|
584
|
+
// 否则如果有路由表格列数据
|
|
585
|
+
const rawTableColumns = utils.$table.config(routePath, 'columns')
|
|
586
|
+
if (utils.isValidArray(rawTableColumns)) {
|
|
587
|
+
columns = _.cloneDeep(rawTableColumns)
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
if (utils.isValidArray(columns)) {
|
|
592
|
+
if (utils.isValidArray(props.hideSearchKeys)) {
|
|
593
|
+
for (const item of columns) {
|
|
594
|
+
if (
|
|
595
|
+
props.hideSearchKeys.indexOf(item.name) > -1
|
|
596
|
+
&& _.has(item, 'search')
|
|
597
|
+
) {
|
|
598
|
+
item.search.hide = true
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return columns
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
return []
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* 获取快捷表格列数据
|
|
610
|
+
*/
|
|
611
|
+
function getQuickTableColumns() {
|
|
612
|
+
|
|
613
|
+
const columns = []
|
|
268
614
|
|
|
269
615
|
// 如果有原始表格列数据
|
|
270
|
-
|
|
616
|
+
if (utils.isValidArray($table.tableColumns)) {
|
|
617
|
+
|
|
271
618
|
// 克隆原始表格列数据
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
619
|
+
const rawTableColumns = _.cloneDeep($table.tableColumns)
|
|
620
|
+
|
|
621
|
+
// 快捷表格显示的属性名称数组
|
|
622
|
+
utils.forEach(currentShowKeys.value, function (key) {
|
|
623
|
+
for (const item of rawTableColumns) {
|
|
624
|
+
if (item.name === key) {
|
|
625
|
+
// 删除搜索字段
|
|
626
|
+
if (_.has(item, 'search')) {
|
|
627
|
+
delete item.search
|
|
628
|
+
}
|
|
629
|
+
// 删除可见字段
|
|
630
|
+
if (_.has(item, 'visible')) {
|
|
631
|
+
delete item.visible
|
|
632
|
+
}
|
|
633
|
+
columns.push(item)
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
})
|
|
637
|
+
}
|
|
275
638
|
|
|
276
|
-
|
|
277
|
-
//
|
|
278
|
-
// // 获取原始表格列数据
|
|
279
|
-
// let rawTableColumns = props.route
|
|
280
|
-
// // 如果有路由组件路径
|
|
281
|
-
// ? utils.$table.config(props.route, 'columns')
|
|
282
|
-
// // 否则为自定义表格列数据
|
|
283
|
-
// : props.columns
|
|
284
|
-
//
|
|
285
|
-
// // 如果有原始表格列数据
|
|
286
|
-
// if (utils.isValidArray(rawTableColumns)) {
|
|
287
|
-
//
|
|
288
|
-
// // 克隆原始表格列数据
|
|
289
|
-
// rawTableColumns = _.cloneDeep(rawTableColumns)
|
|
290
|
-
//
|
|
291
|
-
// // 快捷表格显示的属性名称数组
|
|
292
|
-
// utils.forEach(props.showKeys, function (key) {
|
|
293
|
-
// for (const item of rawTableColumns) {
|
|
294
|
-
// if (item.name === key) {
|
|
295
|
-
// // 删除搜索字段
|
|
296
|
-
// if (_.has(item, 'search')) {
|
|
297
|
-
// delete item.search
|
|
298
|
-
// }
|
|
299
|
-
// // 删除可见字段
|
|
300
|
-
// if (_.has(item, 'visible')) {
|
|
301
|
-
// delete item.visible
|
|
302
|
-
// }
|
|
303
|
-
// columns.push(item)
|
|
304
|
-
// }
|
|
305
|
-
// }
|
|
306
|
-
// })
|
|
307
|
-
// }
|
|
308
|
-
//
|
|
309
|
-
// return columns
|
|
639
|
+
return columns
|
|
310
640
|
}
|
|
311
641
|
|
|
312
642
|
/**
|
|
313
|
-
*
|
|
643
|
+
* 移除已选数据
|
|
314
644
|
*/
|
|
315
|
-
function
|
|
316
|
-
|
|
317
|
-
// onEmit('update:modelValue', oldModelValue)
|
|
645
|
+
function onRemoveSelected(item, index) {
|
|
646
|
+
selected.value.splice(index, 1)
|
|
318
647
|
}
|
|
319
648
|
|
|
320
649
|
/**
|
|
321
|
-
*
|
|
650
|
+
* 字段清空触发
|
|
322
651
|
*/
|
|
323
|
-
function
|
|
652
|
+
function onFieldClear() {
|
|
324
653
|
|
|
325
|
-
//
|
|
326
|
-
|
|
654
|
+
// 清空快捷表格已选数据
|
|
655
|
+
selected.value = []
|
|
656
|
+
|
|
657
|
+
// 关闭弹出层
|
|
658
|
+
popupRef.value.hide()
|
|
327
659
|
}
|
|
328
660
|
|
|
329
661
|
/**
|
|
@@ -331,46 +663,126 @@ export default {
|
|
|
331
663
|
*/
|
|
332
664
|
function onPopupShow() {
|
|
333
665
|
|
|
334
|
-
//
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
666
|
+
// 表格加载(只加载一次)
|
|
667
|
+
$table.tableLoad()
|
|
668
|
+
|
|
669
|
+
// 设置输入框焦点
|
|
670
|
+
setInputFocus()
|
|
339
671
|
}
|
|
340
672
|
|
|
341
673
|
/**
|
|
342
|
-
*
|
|
674
|
+
* 弹出层获取焦点触发
|
|
343
675
|
*/
|
|
344
|
-
function
|
|
676
|
+
function onPopupFocus(e) {
|
|
677
|
+
|
|
678
|
+
// 停止冒泡
|
|
679
|
+
e.stopPropagation()
|
|
680
|
+
|
|
681
|
+
// 设置输入框焦点
|
|
682
|
+
setInputFocus()
|
|
345
683
|
|
|
346
|
-
|
|
347
|
-
fieldFocused.value = false
|
|
684
|
+
window.scrollTo(window.pageXOffset || window.scrollX || document.body.scrollLeft || 0, 0)
|
|
348
685
|
}
|
|
349
686
|
|
|
350
687
|
/**
|
|
351
|
-
*
|
|
688
|
+
* 对话框显示前回调
|
|
352
689
|
*/
|
|
353
|
-
function
|
|
690
|
+
function onDialogBeforeShow() {
|
|
354
691
|
|
|
692
|
+
// 设置当前已选数据
|
|
693
|
+
$table.tableSelected.value = [...selected.value]
|
|
694
|
+
|
|
695
|
+
popupRef.value.hide()
|
|
355
696
|
}
|
|
356
697
|
|
|
357
698
|
/**
|
|
358
|
-
*
|
|
699
|
+
* 对话框显示回调
|
|
359
700
|
*/
|
|
360
|
-
function
|
|
361
|
-
|
|
362
|
-
|
|
701
|
+
function onDialogShow() {
|
|
702
|
+
$table.tableLoad()
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* 对话框隐藏后回调
|
|
707
|
+
*/
|
|
708
|
+
function onDialogHide() {
|
|
709
|
+
|
|
710
|
+
let isReload = true
|
|
711
|
+
|
|
712
|
+
// 清空输入框值
|
|
713
|
+
if (inputValue.value) {
|
|
714
|
+
// 此时清空输入框后, 会自动刷新表格
|
|
715
|
+
inputValue.value = ''
|
|
716
|
+
|
|
717
|
+
// 所以只需要重置搜索值即可, 不需要再重置后刷新表格
|
|
718
|
+
isReload = false
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// 如果有表格搜索值
|
|
722
|
+
if ($table.hasTableSearchValue()) {
|
|
723
|
+
// 表格搜索重置
|
|
724
|
+
$table.tableSearchReset(isReload)
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* 对话框点击确认回调
|
|
730
|
+
*/
|
|
731
|
+
function onDialogConfirm(data) {
|
|
732
|
+
selected.value = [...data]
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* 单击快捷表格行
|
|
737
|
+
*/
|
|
738
|
+
function quickTableRowClick(e, row, index) {
|
|
739
|
+
|
|
740
|
+
// 如果为多选
|
|
741
|
+
if (props.multiple) {
|
|
742
|
+
|
|
743
|
+
const opt = {}
|
|
744
|
+
opt[props.rowKey] = row[props.rowKey]
|
|
745
|
+
|
|
746
|
+
// 获取当前数据索引
|
|
747
|
+
const itemIndex = _.findIndex(selected.value, opt)
|
|
748
|
+
|
|
749
|
+
// 如果不存在
|
|
750
|
+
if (itemIndex === -1) {
|
|
751
|
+
// 则添加
|
|
752
|
+
selected.value.push(row)
|
|
753
|
+
|
|
754
|
+
// 否则
|
|
755
|
+
} else {
|
|
756
|
+
// 删除
|
|
757
|
+
selected.value.splice(itemIndex, 1)
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// 否则为单选
|
|
761
|
+
} else {
|
|
762
|
+
selected.value = [ row ]
|
|
763
|
+
popupRef.value.hide()
|
|
764
|
+
}
|
|
363
765
|
}
|
|
364
766
|
|
|
365
767
|
/**
|
|
366
|
-
*
|
|
768
|
+
* 设置输入框焦点
|
|
367
769
|
*/
|
|
368
|
-
function
|
|
369
|
-
|
|
770
|
+
function setInputFocus() {
|
|
771
|
+
if (inputRef.value) {
|
|
772
|
+
inputRef.value.focus()
|
|
773
|
+
}
|
|
370
774
|
}
|
|
371
775
|
|
|
372
776
|
// ==========【生命周期】=========================================================================================
|
|
373
777
|
|
|
778
|
+
/**
|
|
779
|
+
* 实例被挂载后调用
|
|
780
|
+
*/
|
|
781
|
+
onMounted(async function() {
|
|
782
|
+
|
|
783
|
+
// 初始加载选择数据
|
|
784
|
+
await onLoadSelected()
|
|
785
|
+
})
|
|
374
786
|
|
|
375
787
|
// ==========【返回】=============================================================================================
|
|
376
788
|
|
|
@@ -378,61 +790,58 @@ export default {
|
|
|
378
790
|
// 解构表格实例
|
|
379
791
|
...$table,
|
|
380
792
|
|
|
381
|
-
//
|
|
382
|
-
|
|
793
|
+
// 插槽标识
|
|
794
|
+
slotNames,
|
|
795
|
+
// 显示值
|
|
796
|
+
showValue,
|
|
797
|
+
|
|
798
|
+
// 输入框节点
|
|
799
|
+
inputRef,
|
|
800
|
+
// 输入框值
|
|
801
|
+
inputValue,
|
|
383
802
|
// 弹出层节点
|
|
384
803
|
popupRef,
|
|
385
804
|
// 是否显示对话框
|
|
386
805
|
showDialog,
|
|
806
|
+
// 当前已选数据
|
|
807
|
+
selected,
|
|
808
|
+
// 当前表格列数据
|
|
809
|
+
columns,
|
|
387
810
|
|
|
388
|
-
//
|
|
389
|
-
|
|
811
|
+
// 移除已选数据
|
|
812
|
+
onRemoveSelected,
|
|
813
|
+
// 字段清空触发
|
|
814
|
+
onFieldClear,
|
|
390
815
|
|
|
391
|
-
// 取消
|
|
392
|
-
onCancel,
|
|
393
|
-
// 弹出层显示前回调
|
|
394
|
-
onPopupBeforeShow,
|
|
395
816
|
// 弹出层显示回调
|
|
396
817
|
onPopupShow,
|
|
397
|
-
//
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
//
|
|
405
|
-
|
|
818
|
+
// 弹出层获取焦点触发
|
|
819
|
+
onPopupFocus,
|
|
820
|
+
|
|
821
|
+
// 对话框显示前回调
|
|
822
|
+
onDialogBeforeShow,
|
|
823
|
+
// 对话框显示回调
|
|
824
|
+
onDialogShow,
|
|
825
|
+
// 对话框隐藏后回调
|
|
826
|
+
onDialogHide,
|
|
827
|
+
// 对话框点击确认回调
|
|
828
|
+
onDialogConfirm,
|
|
829
|
+
|
|
830
|
+
// 单击快捷表格行
|
|
831
|
+
quickTableRowClick,
|
|
406
832
|
}
|
|
407
833
|
},
|
|
408
834
|
}
|
|
409
835
|
</script>
|
|
410
836
|
|
|
411
|
-
<style lang="scss"
|
|
837
|
+
<style lang="scss">
|
|
412
838
|
@import "@/assets/sass/var.scss";
|
|
413
839
|
|
|
414
|
-
.
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// 时间容器
|
|
422
|
-
&__time {
|
|
423
|
-
+ .date__settings {
|
|
424
|
-
// 等同 q-pt-sm
|
|
425
|
-
padding-top: map-get($space-sm, 'y');
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* 暗色
|
|
432
|
-
*/
|
|
433
|
-
.body--dark {
|
|
434
|
-
.date__select {
|
|
435
|
-
background-color: $color-gray-86;
|
|
840
|
+
.n-field-table {
|
|
841
|
+
.q-field__input--padding {
|
|
842
|
+
padding-left: 4px;
|
|
843
|
+
min-width: 50px !important;
|
|
844
|
+
cursor: text;
|
|
436
845
|
}
|
|
437
846
|
}
|
|
438
847
|
</style>
|