n20-common-lib 3.0.99 → 3.1.1
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
CHANGED
|
@@ -95,21 +95,22 @@
|
|
|
95
95
|
<div slot="prefix">
|
|
96
96
|
<slot name="prefix"></slot>
|
|
97
97
|
</div>
|
|
98
|
-
<template v-for="filter in
|
|
98
|
+
<template v-for="filter in slotFilters" #[filter.slotName]="{ model }">
|
|
99
|
+
<!-- 有 value 的 slot:传递单个值及 input 回调 -->
|
|
99
100
|
<slot
|
|
101
|
+
v-if="filter.value"
|
|
100
102
|
:name="filter.slotName"
|
|
101
103
|
:model="model"
|
|
102
104
|
:value="searchValue[filter.value]"
|
|
103
105
|
:input="(val) => handleSlotInput(filter.value, val)"
|
|
104
106
|
></slot>
|
|
105
|
-
|
|
106
|
-
<!-- 无 value 的 slot(如 startDate/endDate 多值绑定),传递 searchValue 让父组件自行管理 -->
|
|
107
|
-
<template v-for="filter in slotFiltersWithoutValue" #[filter.slotName]="{ model }">
|
|
107
|
+
<!-- 无 value 的 slot(如 startDate/endDate 多值绑定),传递 searchValue 让父组件自行管理 -->
|
|
108
108
|
<slot
|
|
109
|
+
v-else
|
|
109
110
|
:name="filter.slotName"
|
|
110
111
|
:model="model"
|
|
111
112
|
:search-value="searchValue"
|
|
112
|
-
:update-search-value="
|
|
113
|
+
:update-search-value="(updates) => Object.assign(searchValue, updates)"
|
|
113
114
|
></slot>
|
|
114
115
|
</template>
|
|
115
116
|
<div slot="suffix">
|
|
@@ -152,17 +153,18 @@
|
|
|
152
153
|
:check-ids="form.keyIds"
|
|
153
154
|
@saveCheckData="saveCheckData"
|
|
154
155
|
>
|
|
155
|
-
<template v-for="filter in
|
|
156
|
+
<template v-for="filter in slotFilters" #[filter.slotName]="{ model }">
|
|
157
|
+
<!-- 有 value 的 slot:传递单个值及 input 回调 -->
|
|
156
158
|
<slot
|
|
159
|
+
v-if="filter.value"
|
|
157
160
|
:name="filter.slotName"
|
|
158
161
|
:model="model"
|
|
159
162
|
:value="searchForm[filter.value]"
|
|
160
163
|
:input="(val) => (searchForm[filter.value] = val)"
|
|
161
164
|
></slot>
|
|
162
|
-
|
|
163
|
-
<!-- 无 value 的 slot(如 startDate/endDate 多值绑定),传递 searchForm 让父组件自行管理 -->
|
|
164
|
-
<template v-for="filter in slotFiltersWithoutValue" #[filter.slotName]="{ model }">
|
|
165
|
+
<!-- 无 value 的 slot(如 startDate/endDate 多值绑定),传递 searchForm 让父组件自行管理 -->
|
|
165
166
|
<slot
|
|
167
|
+
v-else
|
|
166
168
|
:name="filter.slotName"
|
|
167
169
|
:model="model"
|
|
168
170
|
:search-value="searchForm"
|
|
@@ -178,18 +180,19 @@
|
|
|
178
180
|
:filter-id="filterId"
|
|
179
181
|
:buss-id="bussId"
|
|
180
182
|
>
|
|
181
|
-
<template v-for="filter in
|
|
183
|
+
<template v-for="filter in slotFilters" #[filter.slotName]="{ model, value, input, disabled }">
|
|
184
|
+
<!-- 有 value 的 slot:传递单个值及 input 回调 -->
|
|
182
185
|
<slot
|
|
186
|
+
v-if="filter.value"
|
|
183
187
|
:name="filter.slotName"
|
|
184
188
|
:model="model"
|
|
185
189
|
:value="searchForm[filter.value]"
|
|
186
190
|
:input="(val) => (searchForm[filter.value] = val)"
|
|
187
191
|
:disabled="disabled"
|
|
188
192
|
></slot>
|
|
189
|
-
|
|
190
|
-
<!-- 无 value 的 slot(如 startDate/endDate 多值绑定),传递 searchForm 让父组件自行管理 -->
|
|
191
|
-
<template v-for="filter in slotFiltersWithoutValue" #[filter.slotName]="{ model, value, input, disabled }">
|
|
193
|
+
<!-- 无 value 的 slot(如 startDate/endDate 多值绑定),传递 searchForm 让父组件自行管理 -->
|
|
192
194
|
<slot
|
|
195
|
+
v-else
|
|
193
196
|
:name="filter.slotName"
|
|
194
197
|
:model="model"
|
|
195
198
|
:search-value="searchForm"
|
|
@@ -292,14 +295,7 @@ export default {
|
|
|
292
295
|
slotFilters() {
|
|
293
296
|
return this.filterList.filter((item) => item.type === 'slot' && this.$scopedSlots[item.slotName])
|
|
294
297
|
},
|
|
295
|
-
|
|
296
|
-
slotFiltersWithValue() {
|
|
297
|
-
return this.slotFilters.filter((item) => item.value)
|
|
298
|
-
},
|
|
299
|
-
// 筛选出无 value 字段的 slot 类型筛选项(如 startDate/endDate 多值绑定)
|
|
300
|
-
slotFiltersWithoutValue() {
|
|
301
|
-
return this.slotFilters.filter((item) => !item.value)
|
|
302
|
-
},
|
|
298
|
+
|
|
303
299
|
getInitialSearchValue() {
|
|
304
300
|
const obj = {}
|
|
305
301
|
// 遍历 filterList,为每个 type 为 slot 且有 value 字段的项初始化值
|
|
@@ -366,10 +362,6 @@ export default {
|
|
|
366
362
|
this.searchValue = { ...this.getInitialSearchValue, ...this.initialValue }
|
|
367
363
|
},
|
|
368
364
|
methods: {
|
|
369
|
-
updateSearchValue(updates) {
|
|
370
|
-
console.log(updates, 'updates')
|
|
371
|
-
Object.assign(searchValue, updates)
|
|
372
|
-
},
|
|
373
365
|
// 处理 slot 类型字段的输入事件,同时更新 searchValue 和 initialValue
|
|
374
366
|
handleSlotInput(fieldName, val) {
|
|
375
367
|
// 防御性检查:如果 fieldName 无效,不执行任何操作
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
}}</el-checkbox>
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
31
|
-
<div class="flex-item p-r" style="height:
|
|
31
|
+
<div class="flex-item p-r" style="height: 80%; overflow: auto">
|
|
32
32
|
<!-- :value 需包含 static 列的 label,使其显示为选中状态 -->
|
|
33
33
|
<el-checkbox-group :value="checkedLabelValues" @change="handleCheckedChange">
|
|
34
34
|
<template v-if="!columnsGroups">
|
|
@@ -587,7 +587,7 @@ export default {
|
|
|
587
587
|
},
|
|
588
588
|
reset() {
|
|
589
589
|
const baseCols = this.columns.length
|
|
590
|
-
? this.columns
|
|
590
|
+
? this.columns.filter((col) => !col.defaultHidden)
|
|
591
591
|
: this.checkColumns.filter((col) => col.static !== 'pre' && col.static !== 'next')
|
|
592
592
|
this.fixedColumns = baseCols.filter((col) => col.fixed)
|
|
593
593
|
this.dragList = baseCols.filter((col) => !col.fixed && !col.static)
|
|
@@ -642,14 +642,16 @@ export default {
|
|
|
642
642
|
}
|
|
643
643
|
}
|
|
644
644
|
|
|
645
|
-
function saveTransform(list, labelKey, isFilter) {
|
|
645
|
+
export function saveTransform(list, labelKey, isFilter) {
|
|
646
646
|
let listN = []
|
|
647
647
|
if (!isFilter) {
|
|
648
648
|
// 遍历列配置列表,将每列转换为存储格式
|
|
649
649
|
list.forEach((c) => {
|
|
650
650
|
// 普通列:有prop属性、无子列、非新增列、无宽度设置
|
|
651
651
|
if (c.prop && !c.children && !c.isNew && !c.width & !c.isNew) {
|
|
652
|
-
|
|
652
|
+
const entry = { _colKey: 'prop', _colVal: c.prop }
|
|
653
|
+
if (c.fixed) entry.fixed = c.fixed
|
|
654
|
+
listN.push(entry)
|
|
653
655
|
}
|
|
654
656
|
// 特殊类型列:多选/序号/展开列
|
|
655
657
|
else if (c.type && ['selection', 'index', 'expand'].includes(c.type)) {
|
|
@@ -703,8 +705,15 @@ function getTransform(list, columnsT, labelKey = 'label') {
|
|
|
703
705
|
if (d._colKey) {
|
|
704
706
|
// 从columnsT中找到d._colKey等于d._colVal的项
|
|
705
707
|
let column = columnsT.find((c) => c[d._colKey] === d._colVal)
|
|
706
|
-
|
|
707
|
-
|
|
708
|
+
if (column) {
|
|
709
|
+
// 将保存的 fixed、width 合并到列对象上(避免直接修改 props)
|
|
710
|
+
if (d.fixed !== undefined || d.width !== undefined) {
|
|
711
|
+
column = { ...column }
|
|
712
|
+
if (d.fixed !== undefined) column.fixed = d.fixed
|
|
713
|
+
if (d.width !== undefined) column.width = d.width
|
|
714
|
+
}
|
|
715
|
+
columns.push(column)
|
|
716
|
+
}
|
|
708
717
|
// 如果d中没有_colKey属性
|
|
709
718
|
} else {
|
|
710
719
|
// 将d添加到columns中
|
|
@@ -302,7 +302,7 @@
|
|
|
302
302
|
@resize="sizeSet"
|
|
303
303
|
@toggle-expand="toggleExpand"
|
|
304
304
|
@toggle-operate-fixed="handleToggleOperateFixed"
|
|
305
|
-
@visible-column="
|
|
305
|
+
@visible-column="handleVisibleColumn"
|
|
306
306
|
/>
|
|
307
307
|
<!-- 操作列的悬浮按钮组 -->
|
|
308
308
|
<transition name="hover-btns-fade">
|
|
@@ -387,7 +387,9 @@
|
|
|
387
387
|
import empty from '../../Empty'
|
|
388
388
|
import tableOperate from '../../TableOperate/index.vue'
|
|
389
389
|
import tableShowColumn from '../../ShowColumn/index.vue'
|
|
390
|
+
import { saveTransform } from '../../ShowColumn/index.vue'
|
|
390
391
|
import OperateBtns from '../../TableProOperateColumn/OperateBtns.vue'
|
|
392
|
+
import axios from '../../../utils/axios'
|
|
391
393
|
|
|
392
394
|
import { $lc } from '../../../utils/i18n/index.js'
|
|
393
395
|
|
|
@@ -590,7 +592,7 @@ export default {
|
|
|
590
592
|
isExpand: false,
|
|
591
593
|
isExport: false, // 是否导出
|
|
592
594
|
dialogVisible: false, // 显示列设置对话框
|
|
593
|
-
checkColumns: this.columns
|
|
595
|
+
checkColumns: this.filterDefaultHidden(this.columns) // 显示列设置对话框中已选择的列(默认过滤 defaultHidden 列)
|
|
594
596
|
}
|
|
595
597
|
},
|
|
596
598
|
computed: {
|
|
@@ -648,7 +650,7 @@ export default {
|
|
|
648
650
|
this.colsKey = this.colsKey + 1
|
|
649
651
|
// 没有 pageId 时,columns 变更同步更新 checkColumns
|
|
650
652
|
if (!this.pageId) {
|
|
651
|
-
this.checkColumns = this.columns
|
|
653
|
+
this.checkColumns = this.filterDefaultHidden(this.columns)
|
|
652
654
|
}
|
|
653
655
|
},
|
|
654
656
|
size(val) {
|
|
@@ -678,32 +680,87 @@ export default {
|
|
|
678
680
|
}
|
|
679
681
|
},
|
|
680
682
|
methods: {
|
|
683
|
+
handleVisibleColumn() {
|
|
684
|
+
this.isExport = false
|
|
685
|
+
this.dialogVisible = !this.dialogVisible
|
|
686
|
+
},
|
|
681
687
|
openExportColumn() {
|
|
682
688
|
this.dialogVisible = true
|
|
683
689
|
this.isExport = true
|
|
684
690
|
},
|
|
685
691
|
resizableChange({ resizeWidth, columnIndex }) {
|
|
686
692
|
this.checkColumns[columnIndex].width = resizeWidth
|
|
687
|
-
if(this.showColumn && this.pageId) {
|
|
688
|
-
this
|
|
693
|
+
if (this.showColumn && this.pageId) {
|
|
694
|
+
this.saveColumns()
|
|
689
695
|
}
|
|
690
696
|
},
|
|
697
|
+
// 过滤 defaultHidden 列:仅在用户未设置过显示列时作为 fallback 使用
|
|
698
|
+
filterDefaultHidden(columns) {
|
|
699
|
+
return columns.filter((col) => !col.defaultHidden)
|
|
700
|
+
},
|
|
701
|
+
// 保存列配置到后端(固定列、列宽调整等场景复用)
|
|
702
|
+
saveColumns() {
|
|
703
|
+
const userNo = sessionStorage.getItem('userNo')
|
|
704
|
+
const columns = saveTransform(this.checkColumns, this.labelKey, this.isFilter)
|
|
705
|
+
axios.post(
|
|
706
|
+
`/bems/prod_1.0/user/pageHabit?t=${Math.random()}`,
|
|
707
|
+
{
|
|
708
|
+
userNo,
|
|
709
|
+
pageId: this.pageId,
|
|
710
|
+
showStructure: JSON.stringify(columns)
|
|
711
|
+
},
|
|
712
|
+
{ loading: false }
|
|
713
|
+
)
|
|
714
|
+
},
|
|
691
715
|
setColumns(list) {
|
|
692
716
|
if (this.isExport) {
|
|
693
717
|
this.exportFn(list)
|
|
718
|
+
this.isExport = false
|
|
694
719
|
} else {
|
|
695
720
|
this.checkColumns = list
|
|
696
721
|
}
|
|
697
722
|
},
|
|
698
723
|
async getColumns() {
|
|
699
724
|
try {
|
|
700
|
-
const columns = await this.$refs
|
|
701
|
-
|
|
725
|
+
const columns = await this.$refs?.showColumn?.getColumns(this.pageId)
|
|
726
|
+
|
|
727
|
+
if (columns?.length) {
|
|
728
|
+
this.checkColumns = columns
|
|
729
|
+
// 将 remote: true 的远程列同步写入 this.columns,保持位置一致
|
|
730
|
+
this.syncRemoteColumns(columns)
|
|
731
|
+
} else {
|
|
732
|
+
this.checkColumns = this.filterDefaultHidden(this.columns)
|
|
733
|
+
}
|
|
702
734
|
} catch (err) {
|
|
703
|
-
// API
|
|
704
|
-
this.checkColumns = this.columns
|
|
735
|
+
// API 请求失败时回退到过滤后的 columns prop
|
|
736
|
+
this.checkColumns = this.filterDefaultHidden(this.columns)
|
|
737
|
+
}
|
|
738
|
+
},
|
|
739
|
+
// 供组件外部调用,刷新表头数据(重新请求 getColumns 并同步远程列)
|
|
740
|
+
async refreshColumns() {
|
|
741
|
+
if (this.showColumn && this.pageId) {
|
|
742
|
+
await this.getColumns()
|
|
743
|
+
// 强制重建 vxe-table,确保列变更后视图正确刷新
|
|
744
|
+
this.colsKey++
|
|
705
745
|
}
|
|
706
746
|
},
|
|
747
|
+
// 将 API 返回中标记 remote: true 的列同步到 this.columns,保持对应位置一致
|
|
748
|
+
syncRemoteColumns(apiColumns) {
|
|
749
|
+
apiColumns.forEach((apiCol, index) => {
|
|
750
|
+
if (!apiCol.remote) return
|
|
751
|
+
// 按 prop 或 labelKey 匹配 this.columns 中是否已存在
|
|
752
|
+
const matchKey = apiCol.prop ? 'prop' : this.labelKey
|
|
753
|
+
const existingIdx = this.columns.findIndex((c) => c[matchKey] === apiCol[matchKey])
|
|
754
|
+
if (existingIdx !== -1) {
|
|
755
|
+
// 已存在则替换,保持位置以 API 返回为准
|
|
756
|
+
this.$set(this.columns, existingIdx, apiCol)
|
|
757
|
+
} else {
|
|
758
|
+
// 不存在则插入到对应位置(避免 $set 索引超出长度产生稀疏数组)
|
|
759
|
+
const insertIdx = Math.min(index, this.columns.length)
|
|
760
|
+
this.columns.splice(insertIdx, 0, apiCol)
|
|
761
|
+
}
|
|
762
|
+
})
|
|
763
|
+
},
|
|
707
764
|
/**
|
|
708
765
|
* 一键展开/折叠表格树形行(仅处理第一层级数据行)
|
|
709
766
|
* 通过 vxe-table 的 setTreeExpand API 批量设置顶层行的展开状态,
|
|
@@ -742,6 +799,10 @@ export default {
|
|
|
742
799
|
this.$set(item, 'fixed', 'left')
|
|
743
800
|
// 手动触发 colsKey 刷新,让 vxe-table 重新渲染列配置
|
|
744
801
|
this.colsKey = this.colsKey + 1
|
|
802
|
+
// 固定列后自动保存到后端
|
|
803
|
+
if (this.showColumn && this.pageId) {
|
|
804
|
+
this.saveColumns()
|
|
805
|
+
}
|
|
745
806
|
},
|
|
746
807
|
// 解锁列:移除 fixed 属性,将该列恢复为普通列
|
|
747
808
|
unlockColumn(item) {
|
|
@@ -749,6 +810,10 @@ export default {
|
|
|
749
810
|
this.$delete(item, 'fixed')
|
|
750
811
|
// 手动触发 colsKey 刷新,让 vxe-table 重新渲染列配置
|
|
751
812
|
this.colsKey = this.colsKey + 1
|
|
813
|
+
// 取消固定后自动保存到后端
|
|
814
|
+
if (this.showColumn && this.pageId) {
|
|
815
|
+
this.saveColumns()
|
|
816
|
+
}
|
|
752
817
|
},
|
|
753
818
|
// 固定操作列为内联列
|
|
754
819
|
fixOperateColumn() {
|
|
@@ -1222,11 +1287,21 @@ export default {
|
|
|
1222
1287
|
}
|
|
1223
1288
|
},
|
|
1224
1289
|
// ========== 列宽计算相关方法 ==========
|
|
1225
|
-
getRowClassName(
|
|
1290
|
+
getRowClassName(args) {
|
|
1291
|
+
const rowClassName = this.$attrs['row-class-name'] || this.$attrs.rowClassName
|
|
1292
|
+
// 用户传入了 row-class-name,以传入的为准
|
|
1293
|
+
if (rowClassName && typeof rowClassName === 'function') {
|
|
1294
|
+
return rowClassName(args)
|
|
1295
|
+
}
|
|
1296
|
+
if (rowClassName && typeof rowClassName === 'string') {
|
|
1297
|
+
return rowClassName
|
|
1298
|
+
}
|
|
1299
|
+
// 用户未传入,选中行高亮
|
|
1226
1300
|
const checkedRows = this.$refs.vxeTable?.getCheckboxRecords(false) || []
|
|
1227
1301
|
const checkedSet = new Set(checkedRows)
|
|
1228
|
-
return checkedSet.has(row) ? 'v3-n20-table-pro__row-checked' : ''
|
|
1302
|
+
return checkedSet.has(args.row) ? 'v3-n20-table-pro__row-checked' : ''
|
|
1229
1303
|
},
|
|
1304
|
+
|
|
1230
1305
|
calcColumnWidth(columns) {
|
|
1231
1306
|
// 常量配置
|
|
1232
1307
|
const CHAR_WIDTH = 20 // 每个字符的平均宽度(像素)
|
|
@@ -1,551 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<dialog-wrap
|
|
3
|
-
ref="dialog"
|
|
4
|
-
v-drag
|
|
5
|
-
class="p-t-0"
|
|
6
|
-
v-bind="$attrs"
|
|
7
|
-
:visible.sync="visible"
|
|
8
|
-
:title="title"
|
|
9
|
-
:width="width"
|
|
10
|
-
:close-on-click-modal="false"
|
|
11
|
-
@open="popOpen"
|
|
12
|
-
>
|
|
13
|
-
<div class="dialog-view">
|
|
14
|
-
<div class="flex-box">
|
|
15
|
-
<div class="left-c flex-column p-t-m bd-r">
|
|
16
|
-
<div class="flex-box flex-v p-r m-b">
|
|
17
|
-
<span>{{ header }}</span>
|
|
18
|
-
<span class="m-l-m color-999">
|
|
19
|
-
{{ '已选' | $lc }}
|
|
20
|
-
<span class="color-main">{{ dragList.length }}</span>
|
|
21
|
-
</span>
|
|
22
|
-
<el-link :underline="false" type="primary" class="m-l-auto" @click="setAll">{{
|
|
23
|
-
setState ? $lc('全部清空') : $lc('全部选中')
|
|
24
|
-
}}</el-link>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="flex-item p-r" style="height: 50%; overflow: auto">
|
|
27
|
-
<el-checkbox-group :value="dragListN.map((d) => d[labelKey])">
|
|
28
|
-
<template v-if="!columnsGroups">
|
|
29
|
-
<el-checkbox
|
|
30
|
-
v-for="(column, i) in columnsAs"
|
|
31
|
-
:key="i"
|
|
32
|
-
v-hover-tooltip="column[labelKey]"
|
|
33
|
-
:label="column[labelKey]"
|
|
34
|
-
:disabled="column.checked"
|
|
35
|
-
class="m-t"
|
|
36
|
-
@change="(val) => checkChange(val, column)"
|
|
37
|
-
>{{ column[labelKey] }}</el-checkbox
|
|
38
|
-
>
|
|
39
|
-
</template>
|
|
40
|
-
<template v-else>
|
|
41
|
-
<div v-for="gp in columnsGroups" :key="gp.groupId" class="m-b">
|
|
42
|
-
<div class="f-s-b font-w600">{{ gp.groupName }}</div>
|
|
43
|
-
<template v-for="(column, i) in columnsAs">
|
|
44
|
-
<el-checkbox
|
|
45
|
-
v-if="column.groupId === gp.groupId"
|
|
46
|
-
:key="i"
|
|
47
|
-
v-hover-tooltip="column[labelKey]"
|
|
48
|
-
:label="column[labelKey]"
|
|
49
|
-
:disabled="column.checked"
|
|
50
|
-
class="m-t"
|
|
51
|
-
@change="(val) => checkChange(val, column)"
|
|
52
|
-
>{{ column[labelKey] }}</el-checkbox
|
|
53
|
-
>
|
|
54
|
-
</template>
|
|
55
|
-
</div>
|
|
56
|
-
</template>
|
|
57
|
-
</el-checkbox-group>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
<div v-if="!hasPX" class="right-c flex-column p-t-m">
|
|
61
|
-
<div class="m-b">
|
|
62
|
-
{{ '当前选定项' | $lc }}
|
|
63
|
-
<el-link type="primary" style="visibility: hidden">{{ '当前选定项' | $lc }}</el-link>
|
|
64
|
-
</div>
|
|
65
|
-
<div class="flex-1 overflow-y">
|
|
66
|
-
<drag-list :list="dragList" :label-key="labelKey" :in-show-column="true" />
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
<div v-else class="right-tree flex-column p-t-m">
|
|
70
|
-
<div class="m-b flex-box flex-lr flex-v">
|
|
71
|
-
{{ '当前选定项' | $lc }}
|
|
72
|
-
<el-link class="m-r-s" :underline="false" icon="n20-icon-xinzeng" @click="add">{{
|
|
73
|
-
'新增字段' | $lc
|
|
74
|
-
}}</el-link>
|
|
75
|
-
</div>
|
|
76
|
-
<el-tree
|
|
77
|
-
ref="menu-tree"
|
|
78
|
-
class="menu-tree"
|
|
79
|
-
:data="dragList"
|
|
80
|
-
:props="{
|
|
81
|
-
children: 'children',
|
|
82
|
-
label: 'label'
|
|
83
|
-
}"
|
|
84
|
-
node-key="prop"
|
|
85
|
-
draggable
|
|
86
|
-
style="width: 200px"
|
|
87
|
-
:allow-drop="allowDrop"
|
|
88
|
-
>
|
|
89
|
-
<span slot-scope="{ node, data }" class="menu-item flex-item flex-box flex-lr flex-v">
|
|
90
|
-
<span>
|
|
91
|
-
<i class="n20-drag-icon n20-icon-tuodong"></i>
|
|
92
|
-
<span
|
|
93
|
-
:class="data.isNew ? 'color-success' : 'color-primary'"
|
|
94
|
-
class="text-ellipsis pointer"
|
|
95
|
-
@click="clickItem(data)"
|
|
96
|
-
>{{ data.label }}</span
|
|
97
|
-
>
|
|
98
|
-
</span>
|
|
99
|
-
<el-link
|
|
100
|
-
class="n20-icon-shanchu"
|
|
101
|
-
:underline="false"
|
|
102
|
-
:disabled="data.checked"
|
|
103
|
-
@click.stop="() => removeMenu(node, data)"
|
|
104
|
-
/>
|
|
105
|
-
</span>
|
|
106
|
-
</el-tree>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
</div>
|
|
110
|
-
<dialogWrap
|
|
111
|
-
v-drag
|
|
112
|
-
:visible.sync="configVisible"
|
|
113
|
-
:title="'表头设置' | $lc"
|
|
114
|
-
width="350px"
|
|
115
|
-
:close-on-click-modal="false"
|
|
116
|
-
>
|
|
117
|
-
<el-form :model="configModel">
|
|
118
|
-
<el-form-item>
|
|
119
|
-
{{ configModel.label }}
|
|
120
|
-
</el-form-item>
|
|
121
|
-
<el-form-item
|
|
122
|
-
:label="'表头宽度' | $lc"
|
|
123
|
-
:rules="[
|
|
124
|
-
{
|
|
125
|
-
type: 'number',
|
|
126
|
-
trigger: ['change', 'blur'],
|
|
127
|
-
validator: validator
|
|
128
|
-
}
|
|
129
|
-
]"
|
|
130
|
-
prop="width"
|
|
131
|
-
>
|
|
132
|
-
<el-input v-model="configModel.width" class="w-224" />
|
|
133
|
-
</el-form-item>
|
|
134
|
-
<el-form-item :label="'是否折行' | $lc">
|
|
135
|
-
<el-radio-group v-model="configModel.wrap">
|
|
136
|
-
<el-radio :label="true">{{ $lc('是') }}</el-radio>
|
|
137
|
-
<el-radio :label="false">{{ $lc('否') }}</el-radio>
|
|
138
|
-
</el-radio-group>
|
|
139
|
-
</el-form-item>
|
|
140
|
-
<el-form-item :label="'是否加粗' | $lc">
|
|
141
|
-
<el-radio-group v-model="configModel.bold">
|
|
142
|
-
<el-radio :label="true">{{ $lc('是') }}</el-radio>
|
|
143
|
-
<el-radio :label="false">{{ $lc('否') }}</el-radio>
|
|
144
|
-
</el-radio-group>
|
|
145
|
-
</el-form-item>
|
|
146
|
-
<el-form-item :label="'对齐方式' | $lc">
|
|
147
|
-
<el-radio-group v-model="configModel.align">
|
|
148
|
-
<el-radio :label="'right'">{{ $lc('右对齐') }}</el-radio>
|
|
149
|
-
<el-radio :label="'left'">{{ $lc('左对齐') }}</el-radio>
|
|
150
|
-
<el-radio :label="'center'">{{ $lc('居中对齐') }}</el-radio>
|
|
151
|
-
</el-radio-group>
|
|
152
|
-
</el-form-item>
|
|
153
|
-
</el-form>
|
|
154
|
-
<div slot="footer">
|
|
155
|
-
<el-button type="primary" @click="configSave">{{ '确定' | $lc }}</el-button>
|
|
156
|
-
</div>
|
|
157
|
-
</dialogWrap>
|
|
158
|
-
<dialogWrap v-drag :visible.sync="configVisibleN" :title="'新增' | $lc" width="350px" :close-on-click-modal="false">
|
|
159
|
-
<el-form :model="configModelN">
|
|
160
|
-
<el-form-item :label="'名称' | $lc" required>
|
|
161
|
-
<el-input v-model="configModelN.label" class="input-w" :placeholder="'请输入' | $lc" />
|
|
162
|
-
</el-form-item>
|
|
163
|
-
</el-form>
|
|
164
|
-
<div slot="footer">
|
|
165
|
-
<el-button type="primary" @click="configSaveN">{{ '确定' | $lc }}</el-button>
|
|
166
|
-
</div>
|
|
167
|
-
</dialogWrap>
|
|
168
|
-
<div slot="footer" class="text-c">
|
|
169
|
-
<el-button type="primary" @click="setChange">{{ '确定' | $lc }}</el-button>
|
|
170
|
-
<el-button plain @click="reset">{{ '恢复默认' | $lc }}</el-button>
|
|
171
|
-
</div>
|
|
172
|
-
</dialog-wrap>
|
|
173
|
-
</template>
|
|
174
|
-
|
|
175
|
-
<script>
|
|
176
|
-
import axios from '../../utils/axios'
|
|
177
|
-
import { $lc } from '../../utils/i18n/index'
|
|
178
|
-
|
|
179
|
-
import { Message } from 'element-ui'
|
|
180
|
-
import forEachs from '../../utils/forEachs'
|
|
181
|
-
import dialogWrap from '../Dialog/index.vue'
|
|
182
|
-
import dragList from '../DragList/index.vue'
|
|
183
|
-
export default {
|
|
184
|
-
name: 'ShowColumn',
|
|
185
|
-
components: { dialogWrap, dragList },
|
|
186
|
-
inheritAttrs: false,
|
|
187
|
-
props: {
|
|
188
|
-
dialogVisible: {
|
|
189
|
-
type: Boolean,
|
|
190
|
-
default: false
|
|
191
|
-
},
|
|
192
|
-
columns: {
|
|
193
|
-
type: Array,
|
|
194
|
-
default: () => []
|
|
195
|
-
},
|
|
196
|
-
columnsGroups: {
|
|
197
|
-
type: Array,
|
|
198
|
-
default: undefined
|
|
199
|
-
},
|
|
200
|
-
checkColumns: {
|
|
201
|
-
type: Array,
|
|
202
|
-
default: () => []
|
|
203
|
-
},
|
|
204
|
-
isExport: {
|
|
205
|
-
type: Boolean,
|
|
206
|
-
default: false
|
|
207
|
-
},
|
|
208
|
-
isFilter: {
|
|
209
|
-
type: Boolean,
|
|
210
|
-
default: false
|
|
211
|
-
},
|
|
212
|
-
labelKey: {
|
|
213
|
-
type: String,
|
|
214
|
-
default: 'label'
|
|
215
|
-
},
|
|
216
|
-
pageId: {
|
|
217
|
-
type: String,
|
|
218
|
-
default: undefined
|
|
219
|
-
},
|
|
220
|
-
autoSave: {
|
|
221
|
-
type: Boolean,
|
|
222
|
-
default: false
|
|
223
|
-
},
|
|
224
|
-
width: {
|
|
225
|
-
type: String,
|
|
226
|
-
default: '1000px'
|
|
227
|
-
},
|
|
228
|
-
hasPX: {
|
|
229
|
-
type: Boolean,
|
|
230
|
-
default: false
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
data() {
|
|
234
|
-
return {
|
|
235
|
-
dragList: [],
|
|
236
|
-
configVisible: false,
|
|
237
|
-
enabled: false,
|
|
238
|
-
configModel: {
|
|
239
|
-
wrap: false,
|
|
240
|
-
bold: false,
|
|
241
|
-
align: 'center'
|
|
242
|
-
},
|
|
243
|
-
configModelN: {
|
|
244
|
-
label: '',
|
|
245
|
-
prop: '',
|
|
246
|
-
width: 120,
|
|
247
|
-
isNew: true,
|
|
248
|
-
children: []
|
|
249
|
-
},
|
|
250
|
-
userNo: sessionStorage.getItem('userNo'),
|
|
251
|
-
configVisibleN: false,
|
|
252
|
-
dragListN: []
|
|
253
|
-
}
|
|
254
|
-
},
|
|
255
|
-
computed: {
|
|
256
|
-
title() {
|
|
257
|
-
if (this.isExport) {
|
|
258
|
-
return $lc('导出')
|
|
259
|
-
} else if (this.isFilter) {
|
|
260
|
-
return $lc('筛选')
|
|
261
|
-
} else {
|
|
262
|
-
return $lc('设置显示列')
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
header() {
|
|
266
|
-
if (this.isExport) {
|
|
267
|
-
return $lc('导出')
|
|
268
|
-
} else if (this.isFilter) {
|
|
269
|
-
return $lc('筛选')
|
|
270
|
-
} else {
|
|
271
|
-
return $lc('显示列')
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
|
-
visible: {
|
|
275
|
-
get() {
|
|
276
|
-
return this.dialogVisible
|
|
277
|
-
},
|
|
278
|
-
set(val) {
|
|
279
|
-
this.$emit('update:dialogVisible', val)
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
setState() {
|
|
283
|
-
const columnsAs = []
|
|
284
|
-
forEachs(this.columnsAs, (item) => {
|
|
285
|
-
columnsAs.push(item)
|
|
286
|
-
})
|
|
287
|
-
return columnsAs.length && columnsAs.length === this.dragListN.length
|
|
288
|
-
// return this.columnsAs.length && this.columnsAs.length === this.dragListN.length
|
|
289
|
-
},
|
|
290
|
-
columnsAs: {
|
|
291
|
-
get() {
|
|
292
|
-
return this.columns.filter((col) => !col.static)
|
|
293
|
-
},
|
|
294
|
-
set(val) {
|
|
295
|
-
return val
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
|
-
columnsN() {
|
|
299
|
-
return this.columns || []
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
watch: {
|
|
303
|
-
dragList: {
|
|
304
|
-
handler() {
|
|
305
|
-
let arr = []
|
|
306
|
-
forEachs(this.dragList, (item) => {
|
|
307
|
-
arr.push(item)
|
|
308
|
-
})
|
|
309
|
-
this.dragListN = arr
|
|
310
|
-
/* const newArr = arr.filter((item) => {
|
|
311
|
-
return item.isNew
|
|
312
|
-
})
|
|
313
|
-
newArr.forEach((item) => {
|
|
314
|
-
const index = this.columns.findIndex((col) => col.prop === item.prop || col.label === item.label)
|
|
315
|
-
if (index === -1) {
|
|
316
|
-
this.columns.push(item)
|
|
317
|
-
}
|
|
318
|
-
}) */
|
|
319
|
-
},
|
|
320
|
-
immediate: true,
|
|
321
|
-
deep: true
|
|
322
|
-
}
|
|
323
|
-
},
|
|
324
|
-
methods: {
|
|
325
|
-
validator(rule, value, callback) {
|
|
326
|
-
if (value) {
|
|
327
|
-
if (value > 300) {
|
|
328
|
-
return callback(new Error($lc('输入最大宽度不能大于300')))
|
|
329
|
-
} else if (!/^[1-9]\d*$/.test(value)) {
|
|
330
|
-
return callback(new Error($lc('表头宽度只能输入正整数')))
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
callback()
|
|
334
|
-
},
|
|
335
|
-
add() {
|
|
336
|
-
this.configVisibleN = true
|
|
337
|
-
this.configModelN.prop = `prop${Date.now()}`
|
|
338
|
-
},
|
|
339
|
-
configSaveN() {
|
|
340
|
-
if (!this.configModelN.label) {
|
|
341
|
-
return this.$message.warning($lc('请填写名称'))
|
|
342
|
-
}
|
|
343
|
-
const hasLabel = this.dragListN.find((item) => {
|
|
344
|
-
return item.label === this.configModelN.label
|
|
345
|
-
})
|
|
346
|
-
if (hasLabel) {
|
|
347
|
-
return this.$message.warning($lc('已有重名字段,请修改'))
|
|
348
|
-
}
|
|
349
|
-
this.dragList.unshift(this.configModelN)
|
|
350
|
-
// this.columns = [this.configModelN, ...this.columns]
|
|
351
|
-
this.$message.success($lc('添加成功'))
|
|
352
|
-
this.configVisibleN = false
|
|
353
|
-
this.configModelN = {
|
|
354
|
-
label: '',
|
|
355
|
-
prop: '',
|
|
356
|
-
width: 120,
|
|
357
|
-
isNew: true,
|
|
358
|
-
children: []
|
|
359
|
-
}
|
|
360
|
-
},
|
|
361
|
-
removeMenu(node, data) {
|
|
362
|
-
const parent = node.parent
|
|
363
|
-
const children = parent.data.children || parent.data
|
|
364
|
-
const index = children.findIndex((d) => d.prop === data.prop)
|
|
365
|
-
children.splice(index, 1)
|
|
366
|
-
},
|
|
367
|
-
allowDrop(draggingNode, dropNode, type) {
|
|
368
|
-
if (type === 'inner' && draggingNode.data.isNew) {
|
|
369
|
-
return !(draggingNode.level <= dropNode.level)
|
|
370
|
-
} else if (type === 'inner' && !draggingNode.data.isNew) {
|
|
371
|
-
return !(draggingNode.level <= dropNode.level && !dropNode.data.isNew)
|
|
372
|
-
} else {
|
|
373
|
-
return true
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
clickItem(item) {
|
|
377
|
-
this.configModel = item
|
|
378
|
-
this.configVisible = true
|
|
379
|
-
},
|
|
380
|
-
configSave() {
|
|
381
|
-
this.configVisible = false
|
|
382
|
-
},
|
|
383
|
-
popOpen() {
|
|
384
|
-
this.dragList = this.checkColumns.filter((col) => !col.static)
|
|
385
|
-
},
|
|
386
|
-
setAll() {
|
|
387
|
-
if (this.setState) {
|
|
388
|
-
this.dragList = this.dragList.filter((c) => c.checked)
|
|
389
|
-
} else {
|
|
390
|
-
this.dragList = [...this.columnsAs]
|
|
391
|
-
}
|
|
392
|
-
},
|
|
393
|
-
checkChange(val, column) {
|
|
394
|
-
if (val === false) {
|
|
395
|
-
let index = this.dragList.findIndex((d) => d[this.labelKey] === column[this.labelKey])
|
|
396
|
-
index !== -1 && this.dragList.splice(index, 1)
|
|
397
|
-
} else {
|
|
398
|
-
let index = this.dragListN.findIndex((d) => d[this.labelKey] === column[this.labelKey])
|
|
399
|
-
if (index !== -1) {
|
|
400
|
-
Message.warning($lc(`子级请在右侧删除!`))
|
|
401
|
-
return false
|
|
402
|
-
}
|
|
403
|
-
this.dragList.push(column)
|
|
404
|
-
}
|
|
405
|
-
},
|
|
406
|
-
reset() {
|
|
407
|
-
let dragList = this.columns.filter((col) => col.isDefault)
|
|
408
|
-
this.dragList = dragList.length ? dragList : this.checkColumns.filter((col) => !col.static)
|
|
409
|
-
},
|
|
410
|
-
setChange() {
|
|
411
|
-
if (this.dragList.length < 1) {
|
|
412
|
-
this.$message.error(
|
|
413
|
-
`${$lc(`至少设置`)}${
|
|
414
|
-
this.isExport ? $lc('一列导出数据') : this.isFilter ? $lc('一个筛选条件') : $lc('一列显示列')
|
|
415
|
-
}!`
|
|
416
|
-
)
|
|
417
|
-
return
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
let list = []
|
|
421
|
-
let preCols = this.columns.filter((col) => col.static === 'pre')
|
|
422
|
-
let nextCols = this.columns.filter((col) => col.static === 'next')
|
|
423
|
-
list.push(...preCols, ...this.dragList, ...nextCols)
|
|
424
|
-
// 新增校验
|
|
425
|
-
if (!this.isExport) {
|
|
426
|
-
let state = list.findIndex((c) => c.isNew && c.children && c.children.length === 0)
|
|
427
|
-
if (state !== -1) {
|
|
428
|
-
Message.warning($lc(`新增字段必须包含子级!`))
|
|
429
|
-
return false
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
// 自动保存设置的显示列
|
|
433
|
-
this.userNo = sessionStorage.getItem('userNo')
|
|
434
|
-
!this.isExport && this.autoSave && this.saveColumns(list)
|
|
435
|
-
|
|
436
|
-
this.$emit('setColumns', list)
|
|
437
|
-
if (this.isExport) {
|
|
438
|
-
this.visible = false
|
|
439
|
-
}
|
|
440
|
-
},
|
|
441
|
-
saveColumns(list) {
|
|
442
|
-
let columns = saveTransform(list, this.labelKey, this.isFilter)
|
|
443
|
-
axios.post(
|
|
444
|
-
`/bems/prod_1.0/user/pageHabit?t=${Math.random()}`,
|
|
445
|
-
{
|
|
446
|
-
userNo: this.userNo,
|
|
447
|
-
pageId: this.pageId,
|
|
448
|
-
showStructure: JSON.stringify(columns)
|
|
449
|
-
},
|
|
450
|
-
{ loading: false }
|
|
451
|
-
)
|
|
452
|
-
this.visible = false
|
|
453
|
-
},
|
|
454
|
-
getColumns(pageId) {
|
|
455
|
-
return getColumns(pageId || this.pageId, this.userNo, this.columnsN, this.labelKey)
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
function saveTransform(list, labelKey, isFilter) {
|
|
461
|
-
let listN = []
|
|
462
|
-
if (!isFilter) {
|
|
463
|
-
list.forEach((c) => {
|
|
464
|
-
if (c.prop && !c.children && !c.isNew && !c.width & !c.isNew) {
|
|
465
|
-
listN.push({ _colKey: 'prop', _colVal: c.prop })
|
|
466
|
-
} else if (c.type && ['selection', 'index', 'expand'].includes(c.type)) {
|
|
467
|
-
listN.push({ _colKey: 'type', _colVal: c.type })
|
|
468
|
-
} else {
|
|
469
|
-
let sFn = false
|
|
470
|
-
for (let k in c) {
|
|
471
|
-
if (typeof c[k] === 'function') sFn = true
|
|
472
|
-
}
|
|
473
|
-
if (sFn && c[labelKey]) {
|
|
474
|
-
listN.push({ _colKey: labelKey, _colVal: c[labelKey] })
|
|
475
|
-
} else {
|
|
476
|
-
listN.push(c)
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
})
|
|
480
|
-
} else {
|
|
481
|
-
list.forEach((c) => {
|
|
482
|
-
if (c.value) {
|
|
483
|
-
listN.push({ _colKey: 'value', _colVal: c.value })
|
|
484
|
-
} else if (c.startValue) {
|
|
485
|
-
listN.push({ _colKey: 'startValue', _colVal: c.startValue })
|
|
486
|
-
} else if (c.startDate) {
|
|
487
|
-
listN.push({ _colKey: 'startDate', _colVal: c.startDate })
|
|
488
|
-
} else {
|
|
489
|
-
listN.push(c)
|
|
490
|
-
}
|
|
491
|
-
})
|
|
492
|
-
}
|
|
493
|
-
return listN
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function getTransform(list, columnsT, labelKey = 'label') {
|
|
497
|
-
let columns = []
|
|
498
|
-
list.forEach((d) => {
|
|
499
|
-
// 如果list中的每一项是字符串
|
|
500
|
-
if (typeof d === 'string') {
|
|
501
|
-
// 从columnsT中找到label等于d的项
|
|
502
|
-
let column = columnsT.find((c) => c[labelKey] === d)
|
|
503
|
-
// 如果找到,则将其添加到columns中
|
|
504
|
-
column && columns.push(column)
|
|
505
|
-
// 如果list中的每一项是对象
|
|
506
|
-
} else if (typeof d === 'object') {
|
|
507
|
-
// 如果d中有_colKey属性
|
|
508
|
-
if (d._colKey) {
|
|
509
|
-
// 从columnsT中找到d._colKey等于d._colVal的项
|
|
510
|
-
let column = columnsT.find((c) => c[d._colKey] === d._colVal)
|
|
511
|
-
// 如果找到,则将其添加到columns中
|
|
512
|
-
column && columns.push(column)
|
|
513
|
-
// 如果d中没有_colKey属性
|
|
514
|
-
} else {
|
|
515
|
-
// 将d添加到columns中
|
|
516
|
-
columns.push(d)
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
})
|
|
520
|
-
// 返回columns
|
|
521
|
-
return columns
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
// 这段代码在筛选组件中复用
|
|
525
|
-
export function getColumns(pageId, userNo, columnsT, labelKey = 'label') {
|
|
526
|
-
return new Promise((resolve, reject) => {
|
|
527
|
-
axios
|
|
528
|
-
.post(
|
|
529
|
-
`/bems/prod_1.0/user/pageHabit/list?t=${Math.random()}`,
|
|
530
|
-
{
|
|
531
|
-
userNo: userNo,
|
|
532
|
-
pageId: pageId
|
|
533
|
-
},
|
|
534
|
-
{ loading: false }
|
|
535
|
-
)
|
|
536
|
-
.then(({ data }) => {
|
|
537
|
-
if (data) {
|
|
538
|
-
let _data = JSON.parse(data)
|
|
539
|
-
if (_data && _data.length > 0) {
|
|
540
|
-
let columns = getTransform(_data, columnsT, labelKey)
|
|
541
|
-
return resolve(columns)
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
return resolve(null)
|
|
545
|
-
})
|
|
546
|
-
.catch((err) => {
|
|
547
|
-
reject(err)
|
|
548
|
-
})
|
|
549
|
-
})
|
|
550
|
-
}
|
|
551
|
-
</script>
|