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

feat(web3): 分页器改 el-pagination + 字段配置抽屉联动真字段

1. ResultTable:自定义分页器换成 el-pagination(带 ... 折叠中间页)

   pageSizes 默认 [10, 25, 50, 100, 200]、defaultPageSize=10

   加 visibleFields prop + allColumns 优先按它过滤(FieldConfigDrawer 联动)

   表格下方加 padding 让分页器不贴表格

2. DataQualityView:字段配置抽屉改从 resultFields(后端 /start 返回的真字段)取

   visibleFields 默认按 show_default=true 重置勾选;用户手动保存后写入

3. TDZ 修复:fields/visibleFields/watch 块挪到 resultFields ref 声明之后

   computed + watch immediate 在 setup 立即跑;const ref 在它前面会 TDZ 报错

   顺手清掉不用的 fieldsByType / violationRows import
parent a4a064dd
......@@ -7,7 +7,7 @@
* row[col.key] 单元格的显示值
* row.errorCells?: [key1, key2] 哪些单元格高亮+tooltip
* row.issues?: [{field, desc}] 备注列要展示的所有错误(每行末尾「备注」列展开)
- props.pageSizes / defaultPageSize 分页每页条数(默认 [5, 10, 20, 50],默认 5)
- 分页:2026-08-21 改用 el-pagination,pageSizes 默认 [25, 50, 100, 200],中间页用 pager 自带 ... 折叠
- 无「操作」列(plan §3 决策;后续如要加,应在父组件再套一层,不要塞回通用组件)
单元格错误展示:
......@@ -106,30 +106,19 @@
</table>
</div>
<!-- 分页:含每页条数选择 -->
<div class="pagination">
<div class="pagination-info">
显示第 {{ rangeStart }}-{{ rangeEnd }} 条 / 共 <span class="highlight">{{ rows.length }}</span> 条
</div>
<div class="pagination-controls">
<select
class="select-input page-size-select"
v-model.number="pageSize"
@change="onPageSizeChange"
>
<option v-for="s in pageSizes" :key="s" :value="s">{{ s }} 条/页</option>
</select>
<button class="page-btn" :disabled="currentPage === 1" @click="currentPage--">‹</button>
<button
v-for="p in totalPages"
:key="p"
class="page-btn"
:class="{ active: currentPage === p }"
@click="currentPage = p"
>{{ p }}</button>
<button class="page-btn" :disabled="currentPage === totalPages" @click="currentPage++">›</button>
</div>
</div>
<!-- 分页:el-pagination 自带「...」省略中间页码(pager 默认行为) -->
<el-pagination
v-if="rows.length > 0"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="pageSizes"
:total="rows.length"
layout="total, sizes, prev, pager, next, jumper"
background
small
class="result-table__pagination"
@current-change="onPageChange"
/>
</div>
</template>
......@@ -139,22 +128,34 @@ import { computed, ref, watch } from 'vue'
const props = defineProps({
columns: { type: Array, required: true }, // [{ key, cn, en, rules, ruleList? }]
rows: { type: Array, required: true }, // 每行:{ errorCells?, issues?, ...业务字段 }
pageSizes: { type: Array, default: () => [5, 10, 20, 50] },
defaultPageSize: { type: Number, default: 5 },
// 2026-08-21:参考 web2 IdCardTable.vue 的 el-pagination 配置
pageSizes: { type: Array, default: () => [10, 25, 50, 100, 200] },
defaultPageSize: { type: Number, default: 10 },
// 行 key:默认用 index;父组件可传 (row, i) => string 走更稳定的 key(如 row.id)
rowKey: { type: Function, default: (_row, i) => i },
// 分页 append 模式(2026-08-21):默认 false(rows 整体替换 → length 变化回到第 1 页)
// 设为 true 时 rows.length 变化不重置页码 —— 用于「分页拉取 + 增量追加」场景
appendMode: { type: Boolean, default: false },
// 2026-08-21:可见字段列表(FieldConfigDrawer 出来的)。
// null 时回退到「按 column.showDefault 过滤」(保持向后兼容 + 老调用方不传)。
visibleFields: { type: Array, default: null },
})
const emit = defineEmits(['page-change'])
// 业务列 + 自动追加的「备注」列
// 任务配置里「默认展示」未勾选的列(showDefault === false)→ 不进结果表
// 兜底:`showDefault !== false` —— 未传 showDefault 的列(mock / 老调用方)全部展示,向后兼容
// 优先级:
// 1. props.visibleFields 非空 → 严格按它过滤(FieldConfigDrawer 出来的用户选择)
// 2. props.visibleFields 为空/null → 回退到「按 column.showDefault 过滤」(向后兼容)
// 兜底:`showDefault !== false` —— 未传 showDefault 的列(mock / 老调用方)全部展示
// rows 为空时(无任务 / 查询 0 行)也不追加备注列 —— 没数据时备注列只会显示「—」占位,没意义
const allColumns = computed(() => {
const cols = props.columns.filter((c) => c.showDefault !== false)
let cols = props.columns.filter((c) => c.key !== '__reason')
if (Array.isArray(props.visibleFields) && props.visibleFields.length > 0) {
const visibleSet = new Set(props.visibleFields)
cols = cols.filter((c) => visibleSet.has(c.key))
} else {
cols = cols.filter((c) => c.showDefault !== false)
}
if (props.rows.length > 0) {
cols.push({ key: '__reason', cn: '备注' })
}
......@@ -170,8 +171,6 @@ const pagedRows = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
return props.rows.slice(start, start + pageSize.value)
})
const rangeStart = computed(() => props.rows.length === 0 ? 0 : (currentPage.value - 1) * pageSize.value + 1)
const rangeEnd = computed(() => Math.min(currentPage.value * pageSize.value, props.rows.length))
// rows 长度变化 → 回到第 1 页(避免翻页中途被切走,停在空页)
// 2026-08-21:append 模式下不重置 —— 新页到达时用户已经看过的页别被强制拉回首屏
......@@ -179,9 +178,8 @@ watch(() => props.rows.length, () => {
if (!props.appendMode) currentPage.value = 1
})
function onPageSizeChange() {
currentPage.value = 1
emit('page-change', { page: currentPage.value, pageSize: pageSize.value })
function onPageChange(page) {
emit('page-change', { page, pageSize: pageSize.value })
}
// ── 单元格渲染辅助 ──
......@@ -234,11 +232,16 @@ function ruleHint(col) {
gap: 4px;
cursor: help;
}
.page-size-select {
margin-right: 12px;
width: auto;
padding: 4px 8px;
font-size: 13px;
/* el-pagination 居中 + 顶部间距(让分页器跟表格拉开距离) */
.result-table__pagination {
display: flex;
justify-content: center;
margin-top: 28px;
margin-bottom: 16px;
}
/* 表格底部留白(防止最后一行贴到分页器 / 卡片底) */
.table-scroll {
padding-bottom: 8px;
}
/* 「备注」列固定在右侧 —— 数据列多了时只滚左侧,备注常驻 */
......
......@@ -81,8 +81,7 @@
<ResultTable
:columns="resultFields"
:rows="rows"
:page-sizes="[5, 10, 20, 50]"
:default-page-size="5"
:visible-fields="visibleFields"
:append-mode="true"
:row-key="rowKeyFn"
@page-change="onPageChange"
......@@ -102,7 +101,7 @@
import { computed, ref, watch, onMounted, onBeforeUnmount } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { fieldsByType, violationRows } from '@/data/mockData' // violationRows 暂留:mock 表头;等真接通后用 resultFields
// mockData 已不引用:表头改为 resultFields(真任务字段),violationRows 同样由 /start 返回
import { listTasks } from '@/api/tasks'
import { startQuery, fetchPage, cancelQuery } from '@/api/queries'
import FieldConfigDrawer from '@/components/FieldConfigDrawer.vue'
......@@ -124,7 +123,7 @@ const TYPE_TO_GROUP = {
}
// 表格字段 mock(仅在没查询前用,避免页面初次加载看起来空;查询后会用 resultFields 覆盖)
const fields = computed(() => fieldsByType[type.value] || [])
// 注:现在 fields 由下方「字段展示开关」段改用 resultFields,跟真任务字段联动
// ── 任务下拉 ──
const taskOptions = ref([])
......@@ -158,10 +157,6 @@ async function loadTasksForCurrentType() {
watch(type, loadTasksForCurrentType, { immediate: true })
onMounted(loadTasksForCurrentType)
// 字段展示开关(默认全开)—— 暂未应用
const visibleFields = ref(fields.value.map((f) => f.key))
watch(fields, (fs) => { visibleFields.value = fs.map((f) => f.key) })
// ── 分页查询 orchestrator(2026-08-21 重构) ──
const PAGE_CONCURRENCY = 3 // 并发 /page 数;> 3 可能压垮 DB
const PAGE_SIZE = 500 // 每页行数,与后端默认对齐
......@@ -180,6 +175,23 @@ const queryError = ref('')
const rows = ref([]) // 喂给 ResultTable 的行
const resultFields = ref([])
// 字段展示开关 —— 跟 resultFields 联动
// 「字段配置」抽屉列出全部 + 默认勾上 show_default=true 的列;
// 用户手动改勾选后写入 visibleFields,ResultTable 按它过滤(优先于 show_default)
// —— 必须在 resultFields 声明之后定义,否则 TDZ 报错(computed/watch 会立即执行)
const fields = computed(() => resultFields.value)
const visibleFields = ref([])
watch(
resultFields,
(rf) => {
// 任务切换 / 新查询完成时,按任务的 show_default 默认勾选
visibleFields.value = (rf || [])
.filter((f) => f.showDefault !== false)
.map((f) => f.key)
},
{ immediate: true },
)
// 行 key:用后端注入的全局行号(append 模式下保证 Vue DOM 复用正确)
const rowKeyFn = (row) => row.__row_index
......
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