feat(面板): 新增processAcceptKeys筛选区域并优化查询功能

- 在面板顶部添加基于processAcceptKeys的动态筛选区域
- 实现查询参数自动初始化与重置功能
- 优化表单样式和交互体验
This commit is contained in:
砂糖
2025-12-31 17:26:49 +08:00
parent 9eb8d46f65
commit b8f5057768

View File

@@ -1,73 +1,70 @@
<!-- ProcessParamCardTemplate.vue 最终版 -->
<!-- ProcessParamCardTemplate.vue 改造后新增processAcceptKeys筛选区 -->
<template>
<div class="panel-container">
<el-row>
<!-- 筛选区域动态渲染processAcceptKeys对应的筛选控件 -->
<el-col :span="19.5">
<el-row :gutter="8" align="middle" class="filter-row">
<!-- 循环processAcceptKeys生成筛选控件 -->
<el-form inline>
<el-form-item v-for="key in processAcceptKeys" :key="key" :label="getFieldLabel(key)" class="filter-form-item" label-width="100px">
<!-- 输入框 -->
<el-input v-if="getFieldComponentType(key) === 'el-input'" v-model="queryParams[key]"
:placeholder="`Please enter ${getFieldLabel(key)}`" size="mini" clearable @keyup.enter="handleQuery" />
<!-- 下拉选择框 -->
<el-select v-else-if="getFieldComponentType(key) === 'el-select'" v-model="queryParams[key]"
:placeholder="`Please select ${getFieldLabel(key)}`" size="mini" clearable @change="handleQuery">
<el-option v-for="item in getFieldOptions(key)" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
<!-- 其他自定义组件兼容扩展 -->
<component v-else :is="getFieldComponentType(key)" v-model="queryParams[key]"
:placeholder="`Please ${getFieldInputHint(key)}`" size="mini" clearable :options="getFieldOptions(key)"
@change="handleQuery" />
</el-form-item>
</el-form>
<!-- 筛选操作按钮查询 + 重置 -->
<el-col :xs="24" :sm="12" :md="6" class="filter-btn-group">
<el-button type="primary" plain icon="el-icon-search" size="mini" @click="handleQuery">Query</el-button>
<el-button type="default" plain icon="el-icon-refresh-left" size="mini" @click="handleResetFilter"
style="margin-left: 8px;">Reset</el-button>
</el-col>
</el-row>
</el-col>
</el-row>
<!-- 顶部操作栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>Add</el-button>
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">Add</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>Export</el-button>
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">Export</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-refresh"
size="mini"
@click="handleRefresh"
>Refresh</el-button>
<el-button type="success" plain icon="el-icon-refresh" size="mini" @click="handleRefresh">Refresh</el-button>
</el-col>
</el-row>
<!-- 卡片网格布局 -->
<div v-loading="loading" class="card-grid-container">
<el-row :gutter="12">
<el-col
v-for="(item, index) in paramList"
:key="index"
:xs="24"
:sm="12"
:md="8"
:lg="6"
:xl="4"
class="card-col"
>
<el-col v-for="(item, index) in paramList" :key="index" :xs="24" :sm="12" :md="8" :lg="6" :xl="4"
class="card-col">
<el-card class="parameter-card" shadow="never" :body-style="{ padding: '10px' }">
<!-- 卡片头部processAcceptKeys 字段编辑禁用的标识字段 -->
<div slot="header" class="card-header">
<span class="card-title">
<template v-for="(key, idx) in processAcceptKeys">
{{ getFieldLabel(key) }}: {{ getFieldDisplayValue(key, item[key]) || '-' }}
{{ idx < processAcceptKeys.length - 1 ? ' | ' : '' }}
</template>
{{ idx < processAcceptKeys.length - 1 ? ' | ' : '' }} </template>
</span>
</div>
<!-- 卡片主体processReturnKeys 字段业务参数 -->
<div class="card-body">
<div
class="param-row"
v-for="(row, rowIdx) in getGroupedReturnKeys"
:key="rowIdx"
>
<div
class="param-item"
v-for="(key, colIdx) in row"
:key="colIdx"
>
<div class="param-row" v-for="(row, rowIdx) in getGroupedReturnKeys" :key="rowIdx">
<div class="param-item" v-for="(key, colIdx) in row" :key="colIdx">
<span class="param-label">{{ getFieldLabel(key) }}:</span>
<span class="param-value">{{ getFieldDisplayValue(key, item[key]) || '-' }}</span>
</div>
@@ -78,24 +75,9 @@
<!-- 卡片底部操作按钮 -->
<div class="card-footer">
<el-button
size="mini"
type="text"
icon="el-icon-copy-document"
@click="handleCopy(item)"
>Copy</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(item)"
>Edit</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(item)"
>Delete</el-button>
<el-button size="mini" type="text" icon="el-icon-copy-document" @click="handleCopy(item)">Copy</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(item)">Edit</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(item)">Delete</el-button>
</div>
</el-card>
</el-col>
@@ -106,58 +88,38 @@
<el-empty description="No data"></el-empty>
</div>
</div>
<!-- 分页组件 -->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 新增/编辑弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="formRules" label-width="100px">
<!-- 第一部分processAcceptKeys编辑禁用新增可编辑 -->
<el-form-item
v-for="(key, idx) in processAcceptKeys"
:key="`accept-${idx}-${key}`"
:label="getFieldLabel(key)"
:prop="key"
>
<el-input v-if="getFieldComponentType(key) == 'el-input'" v-model="form[key]" placeholder="Please enter" :disabled="isEdit"/>
<el-select v-else-if="getFieldComponentType(key) == 'el-select'" v-model="form[key]" placeholder="Please select" :disabled="isEdit">
<el-form-item v-for="(key, idx) in processAcceptKeys" :key="`accept-${idx}-${key}`" :label="getFieldLabel(key)"
:prop="key">
<el-input v-if="getFieldComponentType(key) == 'el-input'" v-model="form[key]" placeholder="Please enter"
:disabled="isEdit" />
<el-select v-else-if="getFieldComponentType(key) == 'el-select'" v-model="form[key]"
placeholder="Please select" :disabled="isEdit">
<el-option v-for="item in getFieldOptions(key)" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<component
v-else
:is="getFieldComponentType(key)"
v-model="form[key]"
:placeholder="`请${getFieldInputHint(key)}${getFieldLabel(key)}`"
:disabled="isEdit"
:options="getFieldOptions(key)"
/>
<component v-else :is="getFieldComponentType(key)" v-model="form[key]"
:placeholder="`请${getFieldInputHint(key)}${getFieldLabel(key)}`" :disabled="isEdit"
:options="getFieldOptions(key)" />
</el-form-item>
<!-- 第二部分processReturnKeys始终可编辑 -->
<el-form-item
v-for="(key, idx) in processReturnKeys"
:key="`return-${idx}-${key}`"
:label="getFieldLabel(key)"
:prop="key"
>
<el-form-item v-for="(key, idx) in processReturnKeys" :key="`return-${idx}-${key}`" :label="getFieldLabel(key)"
:prop="key">
<el-input v-if="getFieldComponentType(key) == 'el-input'" v-model="form[key]" placeholder="Please enter" />
<el-select v-else-if="getFieldComponentType(key) == 'el-select'" v-model="form[key]" placeholder="Please select">
<el-select v-else-if="getFieldComponentType(key) == 'el-select'" v-model="form[key]"
placeholder="Please select">
<el-option v-for="item in getFieldOptions(key)" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<component
v-else
:is="getFieldComponentType(key)"
v-model="form[key]"
:placeholder="`请${getFieldInputHint(key)}${getFieldLabel(key)}`"
:options="getFieldOptions(key)"
/>
<component v-else :is="getFieldComponentType(key)" v-model="form[key]"
:placeholder="`请${getFieldInputHint(key)}${getFieldLabel(key)}`" :options="getFieldOptions(key)" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@@ -220,6 +182,17 @@ export default {
initForm[key] = ''; // 为每个字段初始化空字符串,保证响应式
});
// 初始化查询参数合并分页参数、额外参数、processAcceptKeys空值
const initQueryParams = {
pageNum: 1,
pageSize: 10,
...this.extraQueryParams
};
// 为processAcceptKeys每个字段初始化查询参数空值
this.processAcceptKeys.forEach(key => {
initQueryParams[key] = '';
});
return {
// 加载状态
loading: true,
@@ -231,12 +204,8 @@ export default {
title: "",
// 弹窗显隐
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
...this.extraQueryParams
},
// 查询参数初始化包含processAcceptKeys字段
queryParams: initQueryParams,
// 表单数据(初始化所有字段)
form: initForm,
// 是否为新增状态
@@ -294,14 +263,12 @@ export default {
getFieldDisplayValue(prop, value) {
if (value === '' || value === null || value === undefined) return '-';
const field = this.schema.find(item => item.prop === prop);
console.log(field, 'field', prop, value);
// 有字典转换函数则执行转换
if (field?.dict && typeof field.dict === 'function') {
return field.dict(value);
}
// 下拉选项转换ID转label
if (field?.type === 'el-select' && field?.options.length) {
console.log(field.options, '替换钢种下拉选');
const option = field.options.find(item => item.value == value);
return option ? option.label : value;
}
@@ -327,16 +294,30 @@ export default {
this.getList();
},
/** 搜索操作(适配right-toolbar的queryTable事件 */
/** 搜索操作(适配筛选区查询 */
handleQuery() {
this.queryParams.pageNum = 1;
this.queryParams.pageNum = 1; // 筛选时重置页码为第一页
this.getList();
},
/** 重置筛选条件 */
handleResetFilter() {
// 重置processAcceptKeys对应的筛选字段为空
this.processAcceptKeys.forEach(key => {
this.queryParams[key] = '';
});
// 重置额外查询参数(可选:若需要保留额外参数,可注释此行)
// Object.keys(this.extraQueryParams).forEach(key => {
// this.queryParams[key] = this.extraQueryParams[key];
// });
this.queryParams.pageNum = 1; // 重置页码
this.getList(); // 重新查询
},
/** 查询参数列表 */
getList() {
this.loading = true;
// 合并额外查询参数
// 合并额外查询参数(最终查询参数:分页+筛选+额外参数)
const queryParams = { ...this.queryParams, ...this.extraQueryParams };
this.apis.list(queryParams).then(response => {
this.paramList = response.rows || [];
@@ -390,7 +371,6 @@ export default {
/** 修改操作(优化异常处理和数据赋值) */
handleUpdate(row) {
this.isAdd = false; // 标记为编辑态
console.log(row)
this.resetForm(); // 重置表单
this.apis.get(row).then(response => {
const data = response.data || {};
@@ -402,7 +382,6 @@ export default {
this.open = true;
this.title = `Edit ${this.$options.name || 'Process Parameters'}`;
}).catch(error => {
// 新增错误提示,避免静默失败
this.$modal.msgError('Failed to get details, please try again.');
console.error('获取详情失败:', error);
});
@@ -418,7 +397,6 @@ export default {
this.open = false;
this.getList();
}).catch(error => {
// 新增提交失败提示
this.$modal.msgError(this.isAdd ? "Add failed" : "Update failed");
console.error('提交失败:', error);
});
@@ -433,7 +411,7 @@ export default {
}).then(() => {
this.getList();
this.$modal.msgSuccess("Deleted successfully");
}).catch(() => {});
}).catch(() => { });
},
/** 导出操作 */
@@ -452,29 +430,63 @@ export default {
</script>
<style lang="scss" scoped>
// 样式部分保持不变
// 样式部分新增筛选区样式,其余保持不变
.panel-container {
height: 100%;
display: flex;
flex-direction: column;
}
// 筛选区样式
.filter-row {
padding: 2px 0;
background: #fafafa;
padding: 8px;
border-radius: 4px;
border: 1px solid #e8e8e8;
}
.filter-col {
margin-bottom: 8px;
}
.filter-form-item {
margin-bottom: 0 !important;
font-size: 12px;
::v-deep .el-form-item__label {
font-size: 11px;
color: #666;
}
::v-deep .el-input--mini,
::v-deep .el-select--mini {
width: 100%;
}
}
.filter-btn-group {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.card-grid-container {
flex: 1;
overflow-y: auto;
margin-top: 10px;
padding-right: 5px;
min-height: 0;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #c0c0c0;
border-radius: 3px;
}
&::-webkit-scrollbar-track {
background: #f0f0f0;
}
@@ -488,13 +500,13 @@ export default {
height: 100%;
border: 1px solid #d4d4d4;
border-radius: 2px;
::v-deep .el-card__header {
padding: 8px 10px;
background: #f5f5f5;
border-bottom: 1px solid #d4d4d4;
}
&:hover {
border-color: #999;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
@@ -513,26 +525,26 @@ export default {
.param-row {
display: flex;
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
.param-item {
flex: 1;
display: flex;
flex-direction: column;
padding: 4px 6px;
border-right: 1px solid #e8e8e8;
&:last-child {
border-right: none;
}
&:only-child {
border-right: none;
}
.param-label {
color: #666;
font-size: 11px;
@@ -541,7 +553,7 @@ export default {
overflow: hidden;
text-overflow: ellipsis;
}
.param-value {
color: #333;
font-weight: 500;
@@ -558,7 +570,7 @@ export default {
padding-top: 8px;
border-top: 1px solid #e8e8e8;
margin-top: 8px;
.el-button {
font-size: 12px;
padding: 0 4px;