Commit f33c4901 authored by Data Governance Dev's avatar Data Governance Dev

feat(web3): ResultTable 列宽可拖拽(参照 web2 el-table resizable)

web3 ResultTable 是自定义 table,el-table resizable 不能直接复用,自实现:

1. ResultTable.vue

   columnWidths reactive + startResize/onResizeMove/endResize

   拖拽状态不放 reactive(频繁写不触发响应式刷新整张表格)

   window mousemove/mouseup(用户拖快会脱出 th 丢失 mouseup)

   拖拽过程 document.body user-select=none + cursor col-resize

   onBeforeUnmount 清理监听 + 还原 body 样式

2. global.css

   .resize-handle 样式(透明 + hover 变蓝 409eff)

   table.dq-table 加 table-layout: fixed(auto 时 width 被无视)

   thead th 加 position: relative 让 handle absolute 定位

3. 踩坑:改 Vue setup 的 import 段要核对所有 export 符号

   我改 import 时删了 watch 符号,但 setup 里 line 248 的 watch() 还在用

   → 运行时 ReferenceError: watch is not defined 把页面打白

4. localStorage 列宽持久化没做(用户没要求;后续可加 key→width 存)
parent ef99984a
......@@ -8,6 +8,9 @@
* row.errorCells?: [key1, key2] 哪些单元格高亮+tooltip
* row.issues?: [{field, desc}] 备注列要展示的所有错误(每行末尾「备注」列展开)
- 分页:2026-08-21 改用 el-pagination,pageSizes 默认 [25, 50, 100, 200],中间页用 pager 自带 ... 折叠
- 列宽可拖拽:2026-08-21 自实现(参照 web2 el-table resizable)
th / td 都按 col.key 设 width;th 右侧挂 resize handle;mousedown 启动拖拽
—— 不依赖 el-table,因为我们用的是自定义 dq-table
- 无「操作」列(plan §3 决策;后续如要加,应在父组件再套一层,不要塞回通用组件)
单元格错误展示:
......@@ -27,6 +30,7 @@
v-for="col in allColumns"
:key="col.key"
:class="{ 'col-reason': col.key === '__reason' }"
:style="thStyle(col)"
>
<template v-if="col.key === '__reason'">
<span class="flag">!</span><span class="cn">备注</span>
......@@ -50,6 +54,11 @@
>
<span class="rule-mark">⚠ {{ col.rules }}规则</span>
</el-tooltip>
<!-- 拖拽手柄:吸在 th 最右侧,鼠标移上去变 col-resize -->
<span
class="resize-handle"
@mousedown.prevent="startResize($event, col)"
></span>
</template>
</th>
</tr>
......@@ -60,6 +69,7 @@
v-for="col in allColumns"
:key="col.key"
:class="cellClass(row, col.key)"
:style="tdStyle(col)"
>
<!-- 备注列:所有 issues 列表 -->
<template v-if="col.key === '__reason'">
......@@ -123,7 +133,7 @@
</template>
<script setup>
import { computed, ref, watch } from 'vue'
import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue'
const props = defineProps({
columns: { type: Array, required: true }, // [{ key, cn, en, rules, ruleList? }]
......@@ -142,6 +152,67 @@ const props = defineProps({
})
const emit = defineEmits(['page-change'])
// ── 列宽拖拽(2026-08-21,参照 web2 el-table resizable 自实现)──
// 每列的宽度按 col.key 存;拖动时实时更新;卸载时摘掉 window 监听
const DEFAULT_WIDTH = 140 // 业务列默认宽
const REASON_WIDTH = 220 // 备注列默认宽(原本 min:200 max:260)
const MIN_WIDTH = 60 // 不让用户拖太窄把列头文字截没
const columnWidths = reactive({})
function widthOf(col) {
// 没设过就用默认;备注列用专用默认值(保持原 200~260px 区间)
if (columnWidths[col.key] != null) return columnWidths[col.key]
return col.key === '__reason' ? REASON_WIDTH : DEFAULT_WIDTH
}
function thStyle(col) {
// min-width 防文字溢出撑开;width 用户拖拽值;box-sizing 已由 table 控制
return { width: `${widthOf(col)}px`, minWidth: `${MIN_WIDTH}px` }
}
function tdStyle(col) {
// td 不加 min-width —— 列头锁了宽度后 td 自然跟着收敛
return { width: `${widthOf(col)}px` }
}
// 拖拽状态 —— 不放在 reactive 里(拖拽过程频繁写,不需要触发响应式刷新表格)
// 只需要在 mousedown/move/up 这三个事件里读 X / 写 columnWidths 即可
let resizing = null // { startX, startWidth, key }
function startResize(e, col) {
resizing = {
startX: e.clientX,
startWidth: widthOf(col),
key: col.key,
}
// 鼠标可能拖出 th 才松开,必须挂 window 而不是 th 本身
window.addEventListener('mousemove', onResizeMove)
window.addEventListener('mouseup', endResize)
// 防止拖拽过程中浏览器选中表格文字
document.body.style.userSelect = 'none'
document.body.style.cursor = 'col-resize'
}
function onResizeMove(e) {
if (!resizing) return
const dx = e.clientX - resizing.startX
const next = Math.max(MIN_WIDTH, resizing.startWidth + dx)
columnWidths[resizing.key] = next
}
function endResize() {
resizing = null
window.removeEventListener('mousemove', onResizeMove)
window.removeEventListener('mouseup', endResize)
document.body.style.userSelect = ''
document.body.style.cursor = ''
}
onBeforeUnmount(() => {
// 组件卸载时如果还在拖(极少见,比如拖拽中切路由),摘掉监听
endResize()
})
// 业务列 + 自动追加的「备注」列
// 优先级:
// 1. props.visibleFields 非空 → 严格按它过滤(FieldConfigDrawer 出来的用户选择)
......
......@@ -105,6 +105,8 @@ table.dq-table {
border-collapse: collapse;
font-size: 13px;
min-width: 900px;
/* 列宽拖拽必须 fixed:让 th 设的 width 真的生效(默认 auto 时按内容撑开) */
table-layout: fixed;
}
table.dq-table thead th {
background: #fafafa;
......@@ -113,9 +115,26 @@ table.dq-table thead th {
color: #606266;
border-bottom: 1px solid #ebeef5;
white-space: nowrap;
position: relative; /* 让 .resize-handle 能 absolute 定位到右边 */
}
table.dq-table thead th .cn { color: #1f2937; font-size: 13px; }
table.dq-table thead th .en { color: #909399; font-size: 11px; margin-left: 4px; }
/* 列宽拖拽手柄(2026-08-21,参照 web2 el-table resizable 自实现)
平时 1px 透明竖条,hover 时变蓝提示可拖 */
table.dq-table thead th .resize-handle {
position: absolute;
top: 0;
right: 0;
width: 6px;
height: 100%;
cursor: col-resize;
background: transparent;
transition: background 0.15s;
}
table.dq-table thead th .resize-handle:hover,
table.dq-table thead th.col-resizing .resize-handle {
background: #409eff;
}
table.dq-table thead th .rule-mark {
color: #e6a23c;
margin-left: 4px;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment