feat(面板): 新增processAcceptKeys筛选区域并优化查询功能
- 在面板顶部添加基于processAcceptKeys的动态筛选区域 - 实现查询参数自动初始化与重置功能 - 优化表单样式和交互体验
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user