n20-common-lib 3.1.2 → 3.1.4
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
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
<!-- 内容头部工具栏 -->
|
|
71
71
|
<div class="main-toolbar">
|
|
72
72
|
<div class="toolbar-left">
|
|
73
|
-
<div>
|
|
73
|
+
<div class="toolbar-left-top">
|
|
74
74
|
<h2 class="report-title">{{ currentReport.name }}</h2>
|
|
75
75
|
<div class="add-to-home-btn" @click="handleAddToHome">
|
|
76
76
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
</div>
|
|
82
82
|
<div class="report-stats">
|
|
83
83
|
<span class="stat-item">计算耗时:{{ calculateTime }} ms</span>
|
|
84
|
+
<span class="stat-divider"></span>
|
|
84
85
|
<span class="stat-item">数据条数:{{ dataCount }}</span>
|
|
85
86
|
</div>
|
|
86
87
|
</div>
|
|
@@ -95,42 +96,10 @@
|
|
|
95
96
|
|
|
96
97
|
<div class="action-buttons">
|
|
97
98
|
<div class="action-btn" @click="handleRefresh" title="刷新">
|
|
98
|
-
<
|
|
99
|
-
<path
|
|
100
|
-
d="M13 2.5V6.5H9M1 11.5V7.5H5"
|
|
101
|
-
stroke="currentColor"
|
|
102
|
-
stroke-width="1.5"
|
|
103
|
-
stroke-linecap="round"
|
|
104
|
-
stroke-linejoin="round"
|
|
105
|
-
/>
|
|
106
|
-
<path
|
|
107
|
-
d="M13 2.5C11.5 1 9.5 0.5 7 1C4.5 1.5 2.5 2.5 1.5 4.5C0.5 6.5 0.5 9 2 11C3.5 13 5.5 14 7.5 14C9.5 14 11 13 12 12"
|
|
108
|
-
stroke="currentColor"
|
|
109
|
-
stroke-width="1.5"
|
|
110
|
-
stroke-linecap="round"
|
|
111
|
-
/>
|
|
112
|
-
</svg>
|
|
99
|
+
<i class="n20-icon-shuaxin"></i>
|
|
113
100
|
</div>
|
|
114
|
-
<div class="action-btn" @click="
|
|
115
|
-
<
|
|
116
|
-
<path
|
|
117
|
-
d="M3 9L7 13L11 9"
|
|
118
|
-
stroke="currentColor"
|
|
119
|
-
stroke-width="1.5"
|
|
120
|
-
stroke-linecap="round"
|
|
121
|
-
stroke-linejoin="round"
|
|
122
|
-
/>
|
|
123
|
-
<path d="M7 3V11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
124
|
-
<path
|
|
125
|
-
d="M1 9V11C1 11.5523 1.44772 12 2 12H12C12.5523 12 13 11.5523 13 11V9"
|
|
126
|
-
stroke="currentColor"
|
|
127
|
-
stroke-width="1.5"
|
|
128
|
-
stroke-linecap="round"
|
|
129
|
-
/>
|
|
130
|
-
</svg>
|
|
131
|
-
</div>
|
|
132
|
-
<div class="action-btn" title="折叠" @click="handleToggleRightSidebar">
|
|
133
|
-
<i :class="isRightSidebarCollapsed ? 'v3-icon-move-left' : 'v3-icon-move-right'" class="pointer"></i>
|
|
101
|
+
<div class="action-btn" @click="handleMore" title="更多">
|
|
102
|
+
<i class="v3-icon-more"></i>
|
|
134
103
|
</div>
|
|
135
104
|
</div>
|
|
136
105
|
</div>
|
|
@@ -464,10 +433,7 @@ export default {
|
|
|
464
433
|
// 图表实例
|
|
465
434
|
chartInstance: null,
|
|
466
435
|
// 下拉框显示状态
|
|
467
|
-
|
|
468
|
-
showDimensionDropdown: false,
|
|
469
|
-
showMetricDropdown: false,
|
|
470
|
-
showAggregateDropdown: false,
|
|
436
|
+
showCustomAggregateDropdown: false,
|
|
471
437
|
// 左侧边栏是否折叠
|
|
472
438
|
isLeftSidebarCollapsed: false,
|
|
473
439
|
// 右侧边栏是否折叠
|
|
@@ -806,11 +772,20 @@ export default {
|
|
|
806
772
|
statType: 'group',
|
|
807
773
|
chartType: 'bar',
|
|
808
774
|
dimensions: [],
|
|
809
|
-
metrics: [],
|
|
810
|
-
aggregateType: 'sum'
|
|
775
|
+
metrics: [] // 每项格式: { key: '字段名', aggregateType: 'sum' }
|
|
811
776
|
}
|
|
812
777
|
},
|
|
813
778
|
|
|
779
|
+
// 迁移旧格式报表数据(metrics 从 string[] 迁移为 { key, aggregateType }[])
|
|
780
|
+
migrateReportFormat(report) {
|
|
781
|
+
if (report.metrics && report.metrics.length > 0 && typeof report.metrics[0] === 'string') {
|
|
782
|
+
const aggregateType = report.aggregateType || 'sum'
|
|
783
|
+
report.metrics = report.metrics.map((key) => ({ key, aggregateType }))
|
|
784
|
+
}
|
|
785
|
+
delete report.aggregateType
|
|
786
|
+
return report
|
|
787
|
+
},
|
|
788
|
+
|
|
814
789
|
// 生成唯一ID
|
|
815
790
|
generateId() {
|
|
816
791
|
return 'report_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
|
|
@@ -941,7 +916,8 @@ export default {
|
|
|
941
916
|
if (saved) {
|
|
942
917
|
const configs = JSON.parse(saved)
|
|
943
918
|
if (Array.isArray(configs) && configs.length > 0) {
|
|
944
|
-
|
|
919
|
+
// 迁移旧格式数据
|
|
920
|
+
this.reportList = configs.map((report) => this.migrateReportFormat(report))
|
|
945
921
|
}
|
|
946
922
|
}
|
|
947
923
|
} catch (e) {
|
|
@@ -1377,18 +1353,24 @@ export default {
|
|
|
1377
1353
|
}
|
|
1378
1354
|
|
|
1379
1355
|
.main-toolbar {
|
|
1380
|
-
height: 50px;
|
|
1381
|
-
padding: 0 16px;
|
|
1382
1356
|
display: flex;
|
|
1383
1357
|
align-items: center;
|
|
1384
1358
|
justify-content: space-between;
|
|
1359
|
+
padding: 6px 16px;
|
|
1385
1360
|
border-bottom: 1px solid #e5e6eb;
|
|
1386
1361
|
}
|
|
1387
1362
|
|
|
1388
1363
|
.toolbar-left {
|
|
1364
|
+
display: flex;
|
|
1365
|
+
flex-direction: column;
|
|
1366
|
+
justify-content: center;
|
|
1367
|
+
gap: 4px;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
.toolbar-left-top {
|
|
1389
1371
|
display: flex;
|
|
1390
1372
|
align-items: center;
|
|
1391
|
-
gap:
|
|
1373
|
+
gap: 8px;
|
|
1392
1374
|
}
|
|
1393
1375
|
|
|
1394
1376
|
.report-title {
|
|
@@ -1420,8 +1402,7 @@ export default {
|
|
|
1420
1402
|
.report-stats {
|
|
1421
1403
|
display: flex;
|
|
1422
1404
|
align-items: center;
|
|
1423
|
-
gap:
|
|
1424
|
-
margin-left: 16px;
|
|
1405
|
+
gap: 8px;
|
|
1425
1406
|
}
|
|
1426
1407
|
|
|
1427
1408
|
.stat-item {
|
|
@@ -1429,10 +1410,16 @@ export default {
|
|
|
1429
1410
|
color: #4e5969;
|
|
1430
1411
|
}
|
|
1431
1412
|
|
|
1413
|
+
.stat-divider {
|
|
1414
|
+
width: 0;
|
|
1415
|
+
height: 12px;
|
|
1416
|
+
border-left: 1px solid #e5e6eb;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1432
1419
|
.toolbar-right {
|
|
1433
1420
|
display: flex;
|
|
1434
1421
|
align-items: center;
|
|
1435
|
-
gap:
|
|
1422
|
+
gap: 8px;
|
|
1436
1423
|
}
|
|
1437
1424
|
|
|
1438
1425
|
.action-buttons {
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
v-if="filter.value"
|
|
102
102
|
:name="filter.slotName"
|
|
103
103
|
:model="model"
|
|
104
|
+
:item="filter"
|
|
104
105
|
:value="searchValue[filter.value]"
|
|
105
106
|
:input="(val) => handleSlotInput(filter.value, val)"
|
|
106
107
|
></slot>
|
|
@@ -335,22 +336,20 @@ export default {
|
|
|
335
336
|
if (!newVal) return
|
|
336
337
|
|
|
337
338
|
// 智能合并:保留用户已手动修改的值
|
|
338
|
-
|
|
339
|
-
const mergedValue = { ...this.searchValue }
|
|
340
|
-
|
|
341
|
-
Object.keys(newVal || {}).forEach((key) => {
|
|
342
|
-
// 只有当前值与初始值相同时才更新(说明用户没修改过)
|
|
343
|
-
// 或者 searchValue 中没有这个字段
|
|
344
|
-
if (this.searchValue[key] === undefined || this.searchValue[key] === this.getInitialSearchValue[key]) {
|
|
345
|
-
this.$set(mergedValue, key, newVal[key])
|
|
346
|
-
}
|
|
347
|
-
// 否则保留用户已修改的值
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
this.searchValue = mergedValue
|
|
339
|
+
this.searchValue = newVal
|
|
351
340
|
},
|
|
352
341
|
deep: true,
|
|
353
342
|
immediate: false
|
|
343
|
+
},
|
|
344
|
+
// filterId 变化时重新请求视图列表并重置状态
|
|
345
|
+
filterId: {
|
|
346
|
+
handler(newVal, oldVal) {
|
|
347
|
+
if (newVal && newVal !== oldVal) {
|
|
348
|
+
this.resetState()
|
|
349
|
+
this.getFilterList()
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
immediate: false
|
|
354
353
|
}
|
|
355
354
|
},
|
|
356
355
|
mounted() {
|
|
@@ -362,13 +361,6 @@ export default {
|
|
|
362
361
|
this.searchValue = { ...this.getInitialSearchValue, ...this.initialValue }
|
|
363
362
|
},
|
|
364
363
|
methods: {
|
|
365
|
-
/**
|
|
366
|
-
* 供外部调用更新 GroupData
|
|
367
|
-
* @param {Array} data - 筛选条件数据
|
|
368
|
-
*/
|
|
369
|
-
setGroupData(data) {
|
|
370
|
-
this.$refs.filter.mackData(data || [])
|
|
371
|
-
},
|
|
372
364
|
// 处理 slot 类型字段的输入事件,同时更新 searchValue 和 initialValue
|
|
373
365
|
handleSlotInput(fieldName, val) {
|
|
374
366
|
// 防御性检查:如果 fieldName 无效,不执行任何操作
|
|
@@ -394,7 +386,7 @@ export default {
|
|
|
394
386
|
})
|
|
395
387
|
},
|
|
396
388
|
changeFn(value) {
|
|
397
|
-
|
|
389
|
+
const obj = { ...value }
|
|
398
390
|
const filter = this.filterList.find((item) => item.value === value.field)
|
|
399
391
|
if (filter?.type === 'daterange') {
|
|
400
392
|
obj.value = {
|
|
@@ -452,16 +444,6 @@ export default {
|
|
|
452
444
|
'clear'
|
|
453
445
|
)
|
|
454
446
|
},
|
|
455
|
-
isEnter() {
|
|
456
|
-
this.$rulesValidateForm('ruleValidate', (valid) => {
|
|
457
|
-
if (!valid) {
|
|
458
|
-
console.log('校验不通过')
|
|
459
|
-
this.$message.warning('校验不通过')
|
|
460
|
-
} else {
|
|
461
|
-
this.$message.warning('校验通过')
|
|
462
|
-
}
|
|
463
|
-
})
|
|
464
|
-
},
|
|
465
447
|
// 通过bussId拿取视图列表
|
|
466
448
|
getFilterList(viewId) {
|
|
467
449
|
// 如果没有 bussId,不获取视图列表
|
|
@@ -469,11 +451,10 @@ export default {
|
|
|
469
451
|
return
|
|
470
452
|
}
|
|
471
453
|
|
|
472
|
-
let list = []
|
|
473
454
|
axios
|
|
474
455
|
.get(`/bems/query/viewColumn/getViewInfo`, { bussId: this.bussId })
|
|
475
456
|
.then((res) => {
|
|
476
|
-
list = res.data.map((item) => {
|
|
457
|
+
const list = (res.data || []).map((item) => {
|
|
477
458
|
item.keyIds = this.safeParse(item.keyIds, [])
|
|
478
459
|
return item
|
|
479
460
|
})
|
|
@@ -522,7 +503,6 @@ export default {
|
|
|
522
503
|
// 修改
|
|
523
504
|
edit(item, isRefresh = false) {
|
|
524
505
|
this.isRefresh = isRefresh
|
|
525
|
-
console.log(item)
|
|
526
506
|
this.viewPopoverVisible = false
|
|
527
507
|
this.visible = true
|
|
528
508
|
this.isAdd = false
|
|
@@ -642,7 +622,6 @@ export default {
|
|
|
642
622
|
},
|
|
643
623
|
// 选中视图
|
|
644
624
|
handleSelect(item) {
|
|
645
|
-
console.log(item)
|
|
646
625
|
this.viewPopoverVisible = false
|
|
647
626
|
this.selectItem = item
|
|
648
627
|
this.selectedItem = item.viewName
|
|
@@ -648,7 +648,7 @@ export function saveTransform(list, labelKey, isFilter) {
|
|
|
648
648
|
// 遍历列配置列表,将每列转换为存储格式
|
|
649
649
|
list.forEach((c) => {
|
|
650
650
|
// 普通列:有prop属性、无子列、非新增列、无宽度设置
|
|
651
|
-
if (c.prop && !c.children && !c.isNew && !c.width
|
|
651
|
+
if (c.prop && !c.children && !c.isNew && !c.width && !c.isNew) {
|
|
652
652
|
const entry = { _colKey: 'prop', _colVal: c.prop }
|
|
653
653
|
if (c.fixed) entry.fixed = c.fixed
|
|
654
654
|
listN.push(entry)
|
|
@@ -281,7 +281,12 @@
|
|
|
281
281
|
</div>
|
|
282
282
|
</template>
|
|
283
283
|
<template #default="{ row, $rowIndex }">
|
|
284
|
-
<OperateBtns
|
|
284
|
+
<OperateBtns
|
|
285
|
+
:btn-list="btnList"
|
|
286
|
+
:row="row"
|
|
287
|
+
:get-operate-btns="getOperateBtns"
|
|
288
|
+
@command="(c) => handleOperateCommand(c, row, $rowIndex)"
|
|
289
|
+
/>
|
|
285
290
|
</template>
|
|
286
291
|
</vxe-column>
|
|
287
292
|
<template #empty>
|
|
@@ -526,7 +531,8 @@ export default {
|
|
|
526
531
|
},
|
|
527
532
|
// 悬浮按钮组隐藏延迟(毫秒)
|
|
528
533
|
hoverBtnsHideDelay: {
|
|
529
|
-
type: Number
|
|
534
|
+
type: Number,
|
|
535
|
+
default: 100
|
|
530
536
|
},
|
|
531
537
|
// 悬浮按钮组最大显示数量,超过则收起到"更多"下拉菜单
|
|
532
538
|
hoverBtnsMaxShow: {
|
|
@@ -603,10 +609,15 @@ export default {
|
|
|
603
609
|
computed: {
|
|
604
610
|
_columns: {
|
|
605
611
|
get() {
|
|
612
|
+
// 当操作列已通过模板固定渲染时,过滤掉 checkColumns 中的操作列,避免重复
|
|
613
|
+
const cols =
|
|
614
|
+
this.isOperateFixed && this.btnList && this.btnList.length > 0
|
|
615
|
+
? this.checkColumns.filter((col) => !(col.static && col.label === $lc('操作')))
|
|
616
|
+
: this.checkColumns
|
|
606
617
|
if (this.isAutoWidth) {
|
|
607
|
-
return this.calcColumnWidth(
|
|
618
|
+
return this.calcColumnWidth(cols)
|
|
608
619
|
} else {
|
|
609
|
-
return
|
|
620
|
+
return cols
|
|
610
621
|
}
|
|
611
622
|
},
|
|
612
623
|
set(val) {
|
|
@@ -693,8 +704,14 @@ export default {
|
|
|
693
704
|
this.dialogVisible = true
|
|
694
705
|
this.isExport = true
|
|
695
706
|
},
|
|
696
|
-
resizableChange({ resizeWidth, columnIndex }) {
|
|
697
|
-
|
|
707
|
+
resizableChange({ resizeWidth, column, columnIndex }) {
|
|
708
|
+
// 通过 prop 匹配 checkColumns 中的列,避免 _columns 过滤后索引错位
|
|
709
|
+
const targetCol = column?.property
|
|
710
|
+
? this.checkColumns.find((c) => c.prop === column.property)
|
|
711
|
+
: this.checkColumns[columnIndex]
|
|
712
|
+
if (targetCol) {
|
|
713
|
+
targetCol.width = resizeWidth
|
|
714
|
+
}
|
|
698
715
|
if (this.showColumn && this.pageId) {
|
|
699
716
|
this.saveColumns()
|
|
700
717
|
}
|
|
@@ -706,7 +723,12 @@ export default {
|
|
|
706
723
|
// 保存列配置到后端(固定列、列宽调整等场景复用)
|
|
707
724
|
saveColumns() {
|
|
708
725
|
const userNo = sessionStorage.getItem('userNo')
|
|
709
|
-
|
|
726
|
+
// 排除模板已固定渲染的操作列,避免保存重复数据
|
|
727
|
+
const cols =
|
|
728
|
+
this.isOperateFixed && this.btnList && this.btnList.length > 0
|
|
729
|
+
? this.checkColumns.filter((col) => !(col.static && col.label === $lc('操作')))
|
|
730
|
+
: this.checkColumns
|
|
731
|
+
const columns = saveTransform(cols, this.labelKey, this.isFilter)
|
|
710
732
|
axios.post(
|
|
711
733
|
`/bems/prod_1.0/user/pageHabit?t=${Math.random()}`,
|
|
712
734
|
{
|
|
@@ -723,6 +745,7 @@ export default {
|
|
|
723
745
|
this.isExport = false
|
|
724
746
|
} else {
|
|
725
747
|
this.checkColumns = list
|
|
748
|
+
this.colsKey++
|
|
726
749
|
}
|
|
727
750
|
},
|
|
728
751
|
async getColumns() {
|
|
@@ -941,21 +964,6 @@ export default {
|
|
|
941
964
|
// 得手动触发
|
|
942
965
|
this.handleSelectionChange()
|
|
943
966
|
},
|
|
944
|
-
// 获取被合并的从属行索引集合
|
|
945
|
-
getMergedRowIndexes() {
|
|
946
|
-
const mergedIndexes = new Set()
|
|
947
|
-
if (this.mergeCells && this.mergeCells.length > 0) {
|
|
948
|
-
this.mergeCells.forEach((cell) => {
|
|
949
|
-
if (cell.rowspan > 1) {
|
|
950
|
-
// 从 row+1 到 row+rowspan-1 都是被合并的从属行
|
|
951
|
-
for (let i = 1; i < cell.rowspan; i++) {
|
|
952
|
-
mergedIndexes.add(cell.row + i)
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
})
|
|
956
|
-
}
|
|
957
|
-
return mergedIndexes
|
|
958
|
-
},
|
|
959
967
|
toggleAll($table, disabled) {
|
|
960
968
|
if (disabled) {
|
|
961
969
|
return false
|
|
@@ -1316,18 +1324,9 @@ export default {
|
|
|
1316
1324
|
const HOVER_BTNS_WIDTH = 356 // 悬浮按钮组宽度
|
|
1317
1325
|
const MIN_LABEL_LENGTH = 10 // 最小标签长度
|
|
1318
1326
|
|
|
1319
|
-
// 获取容器宽度
|
|
1320
|
-
let wrapperEl = this.$refs.vxeTable?.$el
|
|
1321
|
-
if (!wrapperEl) wrapperEl = document.querySelector('div#app')
|
|
1322
|
-
if (!wrapperEl) return columns
|
|
1323
|
-
|
|
1324
|
-
const { width: containerWidth } = wrapperEl.getBoundingClientRect()
|
|
1325
|
-
|
|
1326
1327
|
// 解析宽度值(支持数字、"100"、"100px"格式)
|
|
1327
1328
|
const parseWidth = (value) => (typeof value === 'number' ? value : parseInt(value, 10) || 0)
|
|
1328
1329
|
|
|
1329
|
-
// 计算列宽并统计总宽度
|
|
1330
|
-
let totalWidth = 0
|
|
1331
1330
|
const calcColumns = columns.map((column) => {
|
|
1332
1331
|
// 操作列固定宽度
|
|
1333
1332
|
if (column.static && column.label === $lc('操作') && !column.width && !column.minWidth) {
|
|
@@ -1346,7 +1345,6 @@ export default {
|
|
|
1346
1345
|
const widthValue = column.width || column.minWidth || column['min-width'] || 0
|
|
1347
1346
|
const baseWidth = parseWidth(widthValue)
|
|
1348
1347
|
column._baseWidth_ = baseWidth
|
|
1349
|
-
totalWidth += baseWidth
|
|
1350
1348
|
return column
|
|
1351
1349
|
})
|
|
1352
1350
|
|