feat(CoilSelector): 优化钢卷选择器布局和功能

重构钢卷选择器组件布局,改进多选模式下的用户体验。主要变更包括:
1. 调整列顺序和显示内容,优化表格布局
2. 添加全选当前页和清除全部功能按钮
3. 修复对话框滚动问题,优化样式
4. 完善已选钢卷统计区域的布局
5. 增加备注列显示
This commit is contained in:
2026-05-11 11:51:56 +08:00
parent 241105563a
commit 88389b2781
3 changed files with 243 additions and 182 deletions

View File

@@ -947,7 +947,8 @@ body {
.el-dialog.is-fullscreen {
.el-dialog__body {
padding: $--spacing-lg;
max-height: calc(100vh - 100px);
height: calc(100vh - 100px);
max-height: 100vh;
overflow-y: auto;
}
}

View File

@@ -1,5 +1,4 @@
export const defaultColumns = [
{
export const defaultColumns = [{
label: '入场卷号',
align: 'center',
prop: 'enterCoilNo',
@@ -30,6 +29,12 @@ export const defaultColumns = [
prop: 'specification',
width: '100'
},
{
label: '重量(t)',
align: 'center',
prop: 'netWeight',
width: '100'
},
{
label: '材质',
align: 'center',
@@ -42,12 +47,6 @@ export const defaultColumns = [
prop: 'manufacturer',
width: '100'
},
{
label: '重量(t)',
align: 'center',
prop: 'netWeight',
width: '100'
},
{
label: '库区',
align: 'center',
@@ -62,10 +61,10 @@ export const defaultColumns = [
width: '100',
showOverflowTooltip: true
},
{
label: '备注',
align: 'center',
prop: 'remark',
showOverflowTooltip: true
}
]
// {
// label: '备注',
// align: 'center',
// prop: 'remark',
// showOverflowTooltip: true
// }
]

View File

@@ -19,179 +19,190 @@
<el-dialog title="选择钢卷" :visible.sync="dialogVisible" :width="dialogWidth" :close-on-click-modal="false"
@close="handleClose" append-to-body :fullscreen="orderBy">
<!-- 搜索区域 -->
<el-form v-if="!rangeMode" inline :model="queryParams" class="search-form">
<el-form-item label="入场卷号">
<el-input v-model="queryParams.enterCoilNo" placeholder="请输入入场卷号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="当前卷号">
<el-input v-model="queryParams.currentCoilNo" placeholder="请输入当前卷号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="物料类型">
<el-select v-model="queryParams.itemType" placeholder="请选择物料类型" size="small" clearable>
<el-option label="成品" value="product" />
<el-option label="原料" value="raw_material" />
</el-select>
</el-form-item>
<el-form-item label="物料名称" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemName" :options="dict.type.coil_itemname" placeholder="请选择物料名称"
clearable />
</el-form-item>
<el-form-item label="规格" v-if="queryParams.itemType">
<memo-input storageKey="coilSpec" v-model="queryParams.itemSpecification" placeholder="请输入规格" clearable
size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="材质" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemMaterial" :options="dict.type.coil_material" placeholder="请选择材质"
clearable />
</el-form-item>
<el-form-item label="厂家" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemManufacturer" :options="dict.type.coil_manufacturer" placeholder="请选择厂家"
clearable />
</el-form-item>
<el-form-item label="表面处理" v-if="queryParams.itemType">
<el-input v-model="queryParams.itemSurfaceTreatmentDesc" placeholder="请输入表面处理" clearable size="small" />
</el-form-item>
<el-form-item label="切边" prop="trimmingRequirement" v-if="orderBy">
<el-select v-model="queryParams.trimmingRequirement" placeholder="请选择切边" clearable style="width: 100%">
<el-option label="净边" value="净边" />
<el-option label="边" value="边" />
</el-select>
</el-form-item>
<el-form-item label="包装" prop="packagingRequirement" v-if="orderBy">
<el-select v-model="queryParams.packagingRequirement" placeholder="请选择包装" clearable style="width: 100%">
<el-option label="裸包" value="裸包" />
<el-option label="包" value="包" />
<el-option label="包" value="包" />
</el-select>
</el-form-item>
<el-form-item label="品质">
<muti-select v-model="queryParams.qualityStatusCsv" :options="dict.type.coil_quality_status"
placeholder="请选择品质" clearable />
</el-form-item>
<el-form-item label="实际库区" v-if="orderBy">
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择实际库区" canSelectLevel2
canSelectDisabled :clearInput="false" clearable />
</el-form-item>
<div style="height: 100%; overflow-y: scroll; overflow-x: hidden; display: flex; flex-direction: column; padding: 10px;">
<!-- 搜索区域 -->
<el-form v-if="!rangeMode" inline :model="queryParams" class="search-form">
<el-form-item label="入场卷号">
<el-input v-model="queryParams.enterCoilNo" placeholder="请输入入场卷号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="当前卷号">
<el-input v-model="queryParams.currentCoilNo" placeholder="请输入当前卷号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="物料类型">
<el-select v-model="queryParams.itemType" placeholder="请选择物料类型" size="small" clearable>
<el-option label="成品" value="product" />
<el-option label="原料" value="raw_material" />
</el-select>
</el-form-item>
<el-form-item label="物料名称" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemName" :options="dict.type.coil_itemname" placeholder="请选择物料名称"
clearable />
</el-form-item>
<el-form-item label="规格" v-if="queryParams.itemType">
<memo-input storageKey="coilSpec" v-model="queryParams.itemSpecification" placeholder="请输入规格" clearable
size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="材质" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemMaterial" :options="dict.type.coil_material" placeholder="请选择材质"
clearable />
</el-form-item>
<el-form-item label="厂家" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemManufacturer" :options="dict.type.coil_manufacturer"
placeholder="请选择厂家" clearable />
</el-form-item>
<el-form-item label="表面处理" v-if="queryParams.itemType">
<el-input v-model="queryParams.itemSurfaceTreatmentDesc" placeholder="请输入表面处理" clearable size="small" />
</el-form-item>
<el-form-item label="切边" prop="trimmingRequirement" v-if="orderBy">
<el-select v-model="queryParams.trimmingRequirement" placeholder="请选择切边" clearable style="width: 100%">
<el-option label="边" value="边" />
<el-option label="毛边" value="毛边" />
</el-select>
</el-form-item>
<el-form-item label="包装" prop="packagingRequirement" v-if="orderBy">
<el-select v-model="queryParams.packagingRequirement" placeholder="请选择包装" clearable style="width: 100%">
<el-option label="包" value="包" />
<el-option label="包" value="包" />
<el-option label="简包" value="简包" />
</el-select>
</el-form-item>
<el-form-item label="品质">
<muti-select v-model="queryParams.qualityStatusCsv" :options="dict.type.coil_quality_status"
placeholder="请选择品质" clearable />
</el-form-item>
<el-form-item label="实际库区" v-if="orderBy">
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择实际库区" canSelectLevel2
canSelectDisabled :clearInput="false" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
<el-checkbox v-if="orderBy" style="margin-left: 10px;" v-model="showCoilMap" size="small">显示钢卷地图</el-checkbox>
<el-checkbox v-if="orderBy && orderId" style="margin-left: 10px;" v-model="showOrderInfo"
size="small">显示订单详情</el-checkbox>
</el-form-item>
</el-form>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
<el-button v-if="multiple" type="primary" size="small" icon="el-icon-check"
@click="handleSelectAllCurrentPage">全选当前卷</el-button>
<el-checkbox v-if="orderBy" style="margin-left: 10px;" v-model="showCoilMap"
size="small">显示钢卷地图</el-checkbox>
<el-checkbox v-if="orderBy && orderId" style="margin-left: 10px;" v-model="showOrderInfo"
size="small">显示订单详情</el-checkbox>
</el-form-item>
</el-form>
<div v-if="multiple" class="coil-selector-drag-panel">
<DragResizePanel direction="vertical" :initialSize="450" :minSize="200">
<template slot="panelA">
<div style="height: 100%; overflow-y: scroll; overflow-x: hidden;">
<!-- 数据表格 -->
<el-table v-loading="loading" :data="coilList" @row-click="handleRowClick"
style="width: 100%" :row-class-name="getRowClassName">
<!-- 自定义列 -->
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align"
:prop="column.prop" :width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
<el-table-column v-if="orderBy" label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
</el-table>
<!-- 分页 -->
<div
style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 10px; padding-top: 10px;">
<span>
总净重{{ coilTrimStatistics.total_net_weight || 0 }}t
</span>
<pagination v-if="!rangeMode" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
</div>
</template>
<template slot="panelB">
<div v-if="selectedCoils.length > 0" class="panel-b-container">
<div class="selected-stats">
<div class="stats-content">
<div class="stat-item">
<span class="stat-label">总卷数</span>
<span class="stat-value">{{ totalCoils }}</span>
</div>
<div class="stat-item">
<span class="stat-label">总净重</span>
<span class="stat-value">{{ totalNetWeight }}t</span>
</div>
</div>
</div>
<div class="selected-table-wrapper">
<el-table :data="selectedCoils" height="100%">
<div v-if="multiple" class="coil-selector-drag-panel">
<DragResizePanel direction="vertical" :initialSize="450" :minSize="200">
<template slot="panelA">
<div style="height: 100%; overflow-y: scroll; overflow-x: hidden;">
<!-- 数据表格 -->
<el-table v-loading="loading" :data="coilList" @row-click="handleRowClick" style="width: 100%"
:row-class-name="getRowClassName">
<!-- 自定义列 -->
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align"
:prop="column.prop" :width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
<el-table-column v-if="orderBy" label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
<el-table-column label="操作" width="50">
<template slot-scope="scope">
<el-button size="mini" @click="handleRemove(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div
style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 10px; padding-top: 10px;">
<span>
总净重{{ coilTrimStatistics.total_net_weight || 0 }}t
</span>
<pagination v-if="!rangeMode" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
</div>
</div>
<div v-else class="empty-panel">
<el-descriptions title="提示" :column="1" border>
<el-descriptions-item label="说明">
请从上方表格中选择钢卷
</el-descriptions-item>
<el-descriptions-item label="操作方式">
点击上方表格行进行选择再次点击可取消选择
</el-descriptions-item>
<el-descriptions-item label="已选数量">
{{ totalCoils }}
</el-descriptions-item>
</el-descriptions>
</div>
</template>
</DragResizePanel>
</div>
</template>
<template slot="panelB">
<div v-if="selectedCoils.length > 0" class="panel-b-container">
<div class="selected-stats">
<div class="stats-content">
<div class="stat-item">
<span class="stat-label">总卷数</span>
<span class="stat-value">{{ totalCoils }}</span>
</div>
<div class="stat-item">
<span class="stat-label">总净重</span>
<span class="stat-value">{{ totalNetWeight }}t</span>
</div>
</div>
<el-button type="danger" size="small" icon="el-icon-delete"
@click="handleClearAllSelected">全部清除</el-button>
</div>
<!-- 非多选模式的原始布局 -->
<div v-else>
<!-- 数据表格 -->
<el-table v-loading="loading" :data="coilList" @row-click="handleRowClick" height="400px" style="width: 100%"
:row-class-name="getRowClassName">
<!-- 自定义列 -->
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align"
:prop="column.prop" :width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
<el-table-column v-if="orderBy" label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
</el-table>
<div class="selected-table-wrapper">
<el-table :data="selectedCoils" height="100%">
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align"
:prop="column.prop" :width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
<!-- 分页 -->
<div style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 10px;">
<span>
总净重{{ coilTrimStatistics.total_net_weight || 0 }}t
</span>
<el-table-column label="操作" width="50">
<template slot-scope="scope">
<el-button size="mini" @click="handleRemove(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<pagination v-if="!rangeMode" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
<div v-else class="empty-panel">
<el-descriptions title="提示" :column="1" border>
<el-descriptions-item label="说明">
请从上方表格中选择钢卷
</el-descriptions-item>
<el-descriptions-item label="操作方式">
点击上方表格行进行选择再次点击可取消选择
</el-descriptions-item>
<el-descriptions-item label="已选数量">
{{ totalCoils }}
</el-descriptions-item>
</el-descriptions>
</div>
</template>
</DragResizePanel>
</div>
<!-- 单选模式 -->
<div v-else>
<!-- 数据表格 -->
<el-table v-loading="loading" :data="coilList" @row-click="handleRowClick" height="400px" style="width: 100%"
:row-class-name="getRowClassName">
<!-- 自定义列 -->
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align"
:prop="column.prop" :width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
<el-table-column label="备注" prop="remark"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
</el-table>
<!-- 分页 -->
<div style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 10px;">
<span>
总净重{{ coilTrimStatistics.total_net_weight || 0 }}t
</span>
<pagination v-if="!rangeMode" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleConfirm">确认选择</el-button>
<el-button @click="handleClose">取消</el-button>
@@ -503,6 +514,42 @@ export default {
this.selectedCoils = this.selectedCoils.filter(item => item.coilId !== row.coilId);
},
// 全选当前页
handleSelectAllCurrentPage() {
if (!this.multiple) return;
const warehouseIds = ['1988150210872930306', '1988150380649967617', '1988150800092950529', '1988151027466170370'];
const disabledOList = ['O', 'C+', 'C', 'C-', 'D+', 'D', 'D-'];
// 遍历当前页的所有钢卷
this.coilList.forEach(row => {
// 检查是否已选中
if (this.selectedCoils.some(item => item.coilId === row.coilId)) {
return;
}
// 禁用O卷检查逻辑
if (this.disableO) {
// 如果没有判级且不在指定库区,不能选择
if (!row.qualityStatus && !warehouseIds.includes(row.warehouseId)) {
return;
}
// 如果是禁用等级,不能选择
if (disabledOList.includes(row.qualityStatus)) {
return;
}
}
// 添加到已选列表
this.selectedCoils.push(row);
});
},
// 全部清除已选
handleClearAllSelected() {
this.selectedCoils = [];
},
handleConfirm() {
this.$emit('confirm', this.selectedCoils);
this.selectedCoils = [];
@@ -526,7 +573,7 @@ export default {
};
queryPayload.selectType = queryPayload.itemType;
const response = await listMaterialCoil(queryPayload);
const { pageNum, pageSize, excludeBound, orderBy, ...noPager } = queryPayload;
const { pageNum, pageSize, orderBy, ...noPager } = queryPayload;
getCoilStatisticsList(noPager).then((res) => {
console.log('钢卷统计数据:', res);
this.coilTrimStatistics = res.data || {};
@@ -665,6 +712,13 @@ export default {
gap: 8px;
}
.coil-selector-drag-panel {
flex: 1;
min-height: 0;
overflow: hidden;
box-sizing: border-box;
}
// 未选择状态样式
.no-selection {
padding: 8px 12px;
@@ -727,15 +781,11 @@ export default {
}
::v-deep .el-dialog__body {
padding: 20px;
padding: 0 !important;
max-height: calc(100vh - 200px);
overflow-y: auto;
}
// 多选模式拖拽面板容器样式
.coil-selector-drag-panel {
height: 70vh;
max-height: 700px;
min-height: 500px;
overflow-y: hidden !important;
box-sizing: border-box;
}
// panelA容器样式
@@ -768,12 +818,19 @@ export default {
flex-direction: column;
height: 100%;
overflow: hidden;
min-height: 0;
max-height: 100%;
box-sizing: border-box;
}
// 已选表格容器样式
.selected-table-wrapper {
flex: 1;
overflow: hidden;
overflow-y: hidden;
overflow-x: hidden;
min-height: 0;
max-height: calc(100% - 30px);
box-sizing: border-box;
}
// 空面板样式
@@ -815,6 +872,10 @@ export default {
// 已选钢卷统计信息样式
.selected-stats {
display: flex;
justify-content: space-between;
align-items: center;
.stats-content {
display: flex;
gap: 24px;