smart_archives_web/src/views/data-collect/data-set-manage/components/right-table.vue

264 lines
9.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 右侧表格 -->
<div>
<el-card style="min-height: calc(100vh - 125px)">
<!-- 查询 -->
<el-form size="small" ref="queryForm" :inline="true" :model="queryParams">
<el-form-item prop="dataTypeName">
<el-input clearable placeholder="搜索" v-model="queryParams.dataTypeName"
@keyup.enter.native="onHandleQuery" />
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" icon="el-icon-search" @click="onHandleQuery">
查询
</el-button>
<el-button size="mini" icon="el-icon-refresh" @click="onResetQuery">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 表格 -->
<el-table :data="filteredTableData" border :height="tableHeight" style="width: 100%" header-align="center">
<el-table-column v-if="tableData && tableData.length" type="index" label="序号" width="60" align="center" />
<el-table-column align="center" :key="column.prop" :prop="column.prop" :label="column.label"
v-for="column in columns" />
<el-table-column v-if="tableData && tableData.length" label="操作" width="100" align="center" fixed="right" class-name="action-col" label-class-name="action-col-header">
<template slot-scope="{ row }">
<el-button plain type="primary" size="mini" class="action-btn" icon="el-icon-share" @click="handleShare(row)" v-hasPermi="['data:Collect:share']">分享</el-button>
</template>
</el-table-column>
</el-table>
<Share v-if="isflag" :rowData="row" :title="title"
@closeDialog="closeDialog" @showColose="showColose" :dataForm="row" :disabled="loading" :width="600" />
</el-card>
</div>
</template>
<script>
import { getListDataSetAPI } from '@/api/data-collect/data-set-manage'
import Share from './share.vue'
export default {
name: 'RightTable',
components: {
Share
},
props: {
selectedNodeId: {
type: [Number, String],
default: 0,
},
selectedNodeName: {
type: [String],
default: '',
},
},
data() {
return {
isflag: false,
loading: false,
row: {},
title: '分享',
queryParams: {
dataTypeName: undefined,
},
tableData: [],
columns: [],
tableHeight: 400,
filteredManual: null,
}
},
computed: {
// 按第二个字段进行本地过滤
filteredTableData() {
// 仅在点击“查询”后使用过滤结果;输入变化不自动过滤
if (Array.isArray(this.filteredManual)) return this.filteredManual
return this.tableData
},
},
methods: {
// 分享
handleShare(row) {
this.isflag = true;
row.selectedNodeName = this.selectedNodeName;
row.selectedNodeId = this.selectedNodeId;
console.log(row);
this.row = row;
},
closeDialog() {
this.isflag = false;
},
showColose() {
this.isflag = false;
},
// 查询:按第一列字段做模糊匹配
onHandleQuery() {
if (!Array.isArray(this.columns) || this.columns.length < 1) return
const targetProp = this.columns[0] && this.columns[0].prop
if (!targetProp) return
const keyword = String(this.queryParams.dataTypeName || '').trim()
if (!keyword) {
// 空关键字还原
this.filteredManual = null
return
}
// 执行一次性本地过滤
const source = Array.isArray(this.tableData) ? this.tableData : []
const kw = keyword.toLowerCase()
this.filteredManual = source.filter(row => {
const val = row && targetProp in row ? row[targetProp] : ''
return String(val ?? '').toLowerCase().includes(kw)
})
// 触发一次高度计算,避免数据量变化造成滚动体验不佳
this.computeTableHeight()
},
// 重置
onResetQuery() {
this.queryParams = { dataTypeName: undefined }
this.filteredManual = null
this.computeTableHeight()
},
// 获取数据列表
async getListDataSetClassFun(node) {
const params = {
dataClassifyId: node,
}
const res = await getListDataSetAPI(params)
// 安全解析与渲染
this.columns = []
this.tableData = []
if (!res || !Array.isArray(res.rows) || res.rows.length === 0) return
const firstRow = res.rows[0]
if (!firstRow || !firstRow.dataJson) return
let dataList = []
try {
dataList = JSON.parse(firstRow.dataJson)
} catch (e) {
console.warn('数据集 dataJson 解析失败:', e)
return
}
if (!Array.isArray(dataList) || dataList.length === 0) return
const [header, ...rows] = dataList
if (header && typeof header === 'object') {
this.columns = Object.entries(header)
.filter(([prop]) => String(prop).toLowerCase() !== 'id')
.map(([prop, label], index) => ({
label: String(label),
prop: String(prop),
width: index === 0 ? '120' : undefined,
align: index === 0 ? 'left' : 'center',
}))
}
// 将数据行统一转换为对象行,按 columns 的 prop 顺序映射,确保搜索可用
const propOrder = this.columns.map(c => c.prop)
this.tableData = rows.map(row => {
if (Array.isArray(row)) {
const obj = {}
for (let i = 0; i < propOrder.length; i++) {
obj[propOrder[i]] = row[i]
}
return obj
}
return row || {}
})
// 数据变更后重新计算高度
this.computeTableHeight()
},
// 计算表格高度(使用固定 height滚动更顺滑
computeTableHeight() {
this.$nextTick(() => {
const topOffset = this.$el ? this.$el.getBoundingClientRect().top : 0
const formHeight = this.$refs.queryForm && this.$refs.queryForm.$el
? this.$refs.queryForm.$el.offsetHeight
: 0
// 额外预留:卡片内边距、表格头部等
const extra = 100
const available = window.innerHeight - topOffset - formHeight - extra
this.tableHeight = Math.max(260, available)
})
},
},
// 监听选中的节点ID
watch: {
selectedNodeId: {
handler(newVal) {
this.columns = []
this.tableData = []
this.getListDataSetClassFun(newVal)
},
immediate: true, // 表示立即执行
},
selectedNodeName: {
handler(newVal2) {
this.selectedNodeName = newVal2
},
immediate: true, // 表示立即执行
},
},
mounted() {
const onResize = () => this.computeTableHeight()
this.computeTableHeight()
window.addEventListener('resize', onResize)
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', onResize)
})
},
}
</script>
<style scoped>
/* 加粗表格滚动条 */
::v-deep .el-table__body-wrapper::-webkit-scrollbar,
::v-deep .el-table__fixed-body-wrapper::-webkit-scrollbar {
width: 10px; /* 垂直滚动条宽度 */
height: 10px; /* 水平滚动条高度 */
}
::v-deep .el-table__body-wrapper::-webkit-scrollbar-track,
::v-deep .el-table__fixed-body-wrapper::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb,
::v-deep .el-table__fixed-body-wrapper::-webkit-scrollbar-thumb {
background: #bfbfbf;
border-radius: 6px;
}
::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover,
::v-deep .el-table__fixed-body-wrapper::-webkit-scrollbar-thumb:hover {
background: #a6a6a6;
}
/* 操作列样式统一,避免按钮受表格行样式影响抖动或换行 */
/* 操作列单元格与其它列统一高度与内边距,避免不对齐 */
::v-deep .action-col .cell {
display: flex;
align-items: center;
justify-content: center;
padding: 0 8px !important;
height: 100%;
}
::v-deep .action-col-header .cell {
font-weight: 600;
}
.action-btn {
padding: 3px 8px;
line-height: 1;
}
</style>