Files
klp-oa/klp-ui/src/components/CoilSelector/index.vue
砂糖 e23098b766 feat(wms/report): 给成品线圈查询添加按创建时间筛选条件,并增加备注搜索项
1.  在wms报表模板页面的成品线圈查询中,补充byCreateTimeStart和byCreateTimeEnd参数,替换原有的startTime和endTime参数
2.  在CoilSelector组件中新增备注搜索输入框,仅在orderBy存在时显示
2026-05-29 16:27:25 +08:00

1061 lines
34 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 class="coil-selector-container">
<div v-if="useTrigger" class="trigger-container">
<!-- 选择按钮 -->
<div @click="handleOpen">
<slot>
<el-button type="primary" size="small" class="select-button">
<i class="el-icon-search"></i>
<span v-if="selectedCoil">
<span>{{ selectedCoil.currentCoilNo }}</span>
<span>({{ selectedCoil.itemName }})</span>
<span>[{{ selectedCoil.netWeight }}t]</span>
</span>
<span v-else>{{ placeholder }}</span>
</el-button>
</slot>
</div>
</div>
<el-dialog title="选择钢卷" :visible.sync="dialogVisible" :width="dialogWidth" :close-on-click-modal="false"
@close="handleClose" append-to-body :fullscreen="orderBy">
<div
style="height: 100%; overflow-y: scroll; overflow-x: hidden; display: flex; flex-direction: column; padding: 10px;">
<!-- 搜索区域 -->
<div v-if="!rangeMode" style="margin-bottom: 10px; display: flex;">
<el-form 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 label="备注" prop="remark" v-if="orderBy">
<el-input v-model="queryParams.remark" placeholder="请输入备注" clearable size="small" />
</el-form-item>
<el-form-item>
<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 style="display: flex; flex-direction: column; justify-content: flex-start; align-items: center; gap: 2px;">
<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 type="warning" size="small" icon="el-icon-setting"
@click="showColumnSetting = true">列配置</el-button>
</div>
</div>
<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>
<!-- 分页 -->
<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>
<el-button type="danger" size="small" icon="el-icon-delete"
@click="handleClearAllSelected">全部清除</el-button>
</div>
<div class="selected-table-wrapper">
<el-table :data="selectedCoils" :height="orderBy ? 'calc(100% - 30px)' : '200px'">
<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 label="操作" width="50" fixed="right">
<template slot-scope="scope">
<el-button size="mini" @click="handleRemove(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</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>
<!-- 单选模式 -->
<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>
<!-- 分页 -->
<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>
</div>
<!-- 一个可以拖拽和调节大小的浮层 -->
<DragResizeBox v-if="showCoilMap" @size-change="handleSizeChange" storageKey="coil-map">
<div style="height: 100%; width: 100%; overflow-y: scroll; display: flex; background-color: #fff;">
<div style="min-width: 150px; position: sticky; top: 0;" v-loading="treeLoading">
<el-tree ref="warehouseTreeRef" :data="warehouseTree" :props="treeProps" node-key="actualWarehouseId"
@node-click="handleNodeClick" :expand-on-click-node="false" highlight-current class="warehouse-tree">
</el-tree>
</div>
<warehouse-bird-mini ref="warehouseBirdMini" v-loading="warehouseLoading" :warehouseList="warehouseList"
:id="selectedNodeId" :canToggle="false" :canRelease="false" />
</div>
</DragResizeBox>
<DragResizeBox v-if="orderBy && orderId && showOrderInfo" storageKey="coil-order-info">
<div style="height: 100%; width: 100%; background-color: #fff;">
<order-detail v-if="orderBy && orderId && showOrderInfo" :orderId="orderId" :editable="false" />
</div>
</DragResizeBox>
<el-dialog title="列配置" :visible.sync="showColumnSetting" width="800px" append-to-body>
<el-table :data="displayColumns" style="width: 100%" border row-key="prop" height="400">
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-button size="mini" @click="moveColumnUp(scope.$index)"
:disabled="scope.$index === 0 || scope.row._isEmpty">上移</el-button>
<el-button size="mini" @click="moveColumnDown(scope.$index)"
:disabled="scope.$index === displayColumns.length - 1 || scope.row._isEmpty">下移</el-button>
<el-button size="mini" type="danger" @click="removeColumn(scope.$index)"
:disabled="scope.row._isEmpty">删除</el-button>
</template>
</el-table-column>
<el-table-column prop="prop" label="字段名称">
<template slot-scope="scope">
<el-select v-model="scope.row.prop" filterable @change="(value) => columnPropChange(value, scope.row)"
size="small">
<el-option v-for="item in optionalColumns" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="label" label="表头名称">
<template slot-scope="scope">
<el-input v-model="scope.row.label" @blur="saveColumnConfig" size="small" />
</template>
</el-table-column>
<el-table-column prop="width" label="宽度(不填则均分剩余宽度)">
<template slot-scope="scope">
<el-input v-model="scope.row.width" @blur="saveColumnConfig" size="small" />
</template>
</el-table-column>
<el-table-column prop="align" label="对齐方式">
<template slot-scope="scope">
<el-select v-model="scope.row.align" @change="saveColumnConfig" size="small">
<el-option label="左对齐" value="left" />
<el-option label="居中" value="center" />
<el-option label="右对齐" value="right" />
</el-select>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="resetColumnConfig">恢复默认</el-button>
<el-button type="primary" @click="confirmColumnConfig">确定</el-button>
</div>
</el-dialog>
</el-dialog>
</div>
</template>
<script>
import { listMaterialCoil, getCoilStatisticsList } from '@/api/wms/coil';
import { listActualWarehouse } from "@/api/wms/actualWarehouse";
import { treeActualWarehouseTwoLevel } from "@/api/wms/actualWarehouse";
import MemoInput from '@/components/MemoInput/index.vue';
import MutiSelect from '@/components/MutiSelect/index.vue';
import { defaultColumns, fullPageDefaultColumns, optionalColumns } from './data';
import ActualWarehouseSelect from '@/components/KLPService/ActualWarehouseSelect/index.vue';
import WarehouseBirdMini from '@/views/wms/warehouse/components/WarehouseBirdMini.vue';
import DragResizeBox from '@/components/DragResizeBox/index.vue';
import DragResizePanel from '@/components/DragResizePanel/index.vue';
import OrderDetail from '@/views/crm/components/OrderDetail.vue';
export default {
name: 'CoilSelector',
components: {
MemoInput,
MutiSelect,
ActualWarehouseSelect,
WarehouseBirdMini,
DragResizeBox,
DragResizePanel,
OrderDetail
},
dicts: ['coil_itemname', 'coil_material', 'coil_manufacturer', 'coil_quality_status'],
props: {
// 非触发器模式下,外部控制显隐(触发器模式下无效)
visible: {
type: Boolean,
default: false
},
dialogWidth: {
type: String,
default: '1200px'
},
// 过滤条件(可以预设一些查询条件)
filters: {
type: Object,
default: () => ({})
},
placeholder: {
type: String,
default: '请选择钢卷'
},
value: {
type: [String, Number],
default: ''
},
// 是否使用内部触发器(按钮)
useTrigger: {
type: Boolean,
default: true
},
// 初始选中的钢卷数据(支持外部传入已选数据)
initialCoil: {
type: Object,
default: null
},
rangeMode: {
type: Boolean,
default: false
},
// 范围选择模式不再通过list借口获取而是传入可以选择的钢卷数据
rangeData: {
type: Array,
default: () => []
},
// 自定义钢卷列的配置
coilColumn: {
type: Array,
default: () => []
},
// 是否根据实际库区查询钢卷
orderBy: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
// 是否禁用O卷
disableO: {
type: Boolean,
default: false
},
orderId: {
type: String,
default: null
},
defaultType: {
type: String,
default: 'product'
},
},
data() {
return {
showCoilMap: false,
loading: false,
coilList: [],
total: 0,
// 内部显隐控制变量(触发器模式下使用)
innerVisible: false,
// 选中的钢卷数据
selectedCoil: null,
queryParams: {
pageNum: 1,
pageSize: 50,
currentCoilNo: null,
grade: null,
itemSpecification: null,
itemMaterial: null,
itemManufacturer: null,
actualWarehouseId: null,
itemType: this.defaultType,
selectType: this.defaultType,
status: 0,
dataType: 1
},
optionalColumns,
selectedCoils: [],
warehouseList: [],
selectedNodeId: null,
warehouseLoading: false,
warehouseTree: [],
treeProps: { label: "actualWarehouseName", children: "children" },
treeLoading: false,
showOrderInfo: false,
coilTrimStatistics: {},
showColumnSetting: false,
columnsConfig: [],
columnsConfigVersion: 0,
};
},
computed: {
// 根据模式决定对话框显隐逻辑
dialogVisible: {
get() {
// 触发器模式:使用内部变量
if (this.useTrigger) {
return this.innerVisible;
}
// 非触发器模式使用外部传入的visible属性
return this.visible;
},
set(val) {
if (this.useTrigger) {
// 触发器模式:更新内部变量
this.innerVisible = val;
} else {
// 非触发器模式:通知父组件更新
this.$emit('update:visible', val);
}
}
},
renderColumns() {
const _ = this.columnsConfigVersion;
if (this.coilColumn.length > 0) {
return this.coilColumn;
}
const storageKey = this.columnStorageKey;
const savedConfig = localStorage.getItem(storageKey);
if (savedConfig) {
try {
const config = JSON.parse(savedConfig);
if (config.length > 0) {
return config;
}
} catch (e) {
console.error('解析列配置失败', e);
}
}
return this.orderBy ? fullPageDefaultColumns : defaultColumns;
},
columnStorageKey() {
return `coil-selector-columns-${this.orderBy ? 'full' : 'default'}`;
},
displayColumns() {
const displayData = [...this.columnsConfig];
displayData.push({
label: "",
prop: "",
width: "100",
align: "center",
_isEmpty: true
});
return displayData;
},
// 已选钢卷ID集合用于快速判断
selectedCoilIds() {
if (this.multiple) {
return new Set(this.selectedCoils.map(item => item.coilId));
} else {
return this.selectedCoil ? new Set([this.selectedCoil.coilId]) : new Set();
}
},
// 已选钢卷总数量
totalCoils() {
return this.selectedCoils.length;
},
// 已选钢卷总净重
totalNetWeight() {
return this.selectedCoils.reduce((total, item) => {
const weight = parseFloat(item.netWeight) || 0;
return total + weight;
}, 0).toFixed(2);
}
},
watch: {
// 监听对话框显隐状态变化,触发数据加载
dialogVisible(val) {
if (val) {
this.resetQuery();
// this.getList();
}
},
// 非触发器模式下监听外部visible属性变化
visible(val) {
if (!this.useTrigger && val !== this.dialogVisible) {
this.dialogVisible = val;
}
},
// 监听初始钢卷数据变化
initialCoil(val) {
if (val && typeof val === 'object') {
this.selectedCoil = val;
// 同步到v-model
if (this.useTrigger && val.coilId) {
this.$emit('input', val.coilId);
this.$emit('change', val.coilId, val);
}
}
},
// 监听v-model值变化外部修改时同步
value(val) {
if (!val) {
this.handleClearSelection();
return;
}
if (val && !this.selectedCoil?.coilId) {
this.matchCoilById(val);
}
},
showColumnSetting(val) {
if (val) {
this.loadColumnConfig();
}
}
},
created() {
// 初始化时如果有初始钢卷数据,设置选中状态
if (this.initialCoil) {
this.selectedCoil = this.initialCoil;
}
if (this.orderBy) {
this.getWarehouseTree();
}
},
methods: {
// 获取库位列表
getWarehouseList(parentId) {
this.warehouseLoading = true;
return listActualWarehouse({ parentId })
.then((res) => { this.warehouseList = res.data || []; this.warehouseLoading = false; })
.catch((err) => {
this.$message.error("获取库位数据失败:" + err.message);
this.warehouseList = [];
this.warehouseLoading = false;
});
},
handleNodeClick(data) {
console.log('data', data);
if (data.actualWarehouseType != 2) {
return;
}
this.selectedNodeId = data.actualWarehouseId;
this.getWarehouseList(data.actualWarehouseId);
},
// 获取树形数据
getWarehouseTree() {
this.treeLoading = true;
treeActualWarehouseTwoLevel()
.then((res) => { this.warehouseTree = res.data || []; })
.catch((err) => { this.$message.error("获取仓库树形数据失败:" + err.message); })
.finally(() => { this.treeLoading = false; });
},
// 处理大小变化
handleSizeChange(size) {
console.log('size', size);
this.$refs.warehouseBirdMini.resize();
},
// 处理实际库区选择变化
handleWarehouseChange(val) {
console.log('val', val);
if (!val) {
this.selectedNodeId = null;
this.warehouseList = [];
return;
}
if (val.pathIds.length == 2) {
this.selectedNodeId = val;
this.getWarehouseList(val.id);
}
},
// 动态生成表格行类名 - 综合处理选中、禁用等状态
getRowClassName({ row }) {
const classNames = [];
// 检查是否为已选中的钢卷
if (this.selectedCoilIds.has(row.coilId)) {
classNames.push('selected-coil-row');
}
return classNames.join(' ');
},
handleRemove(row) {
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 = [];
this.handleClose();
},
// 获取钢卷列表
async getList() {
// 如果是范围模式,直接使用传入数据
if (this.rangeMode) {
this.coilList = this.rangeData || [];
this.total = this.coilList.length;
return;
}
try {
this.loading = true;
// 设置筛选条件
const queryPayload = {
...this.queryParams,
...this.filters,
};
queryPayload.selectType = queryPayload.itemType;
const response = await listMaterialCoil(queryPayload);
const { pageNum, pageSize, orderBy, ...noPager } = queryPayload;
getCoilStatisticsList(noPager).then((res) => {
console.log('钢卷统计数据:', res);
this.coilTrimStatistics = res.data || {};
});
if (response.code === 200) {
this.coilList = response.rows || [];
this.total = response.total || 0;
// 如果有初始coilId尝试匹配数据
if (this.value && !this.selectedCoil) {
this.matchCoilById(this.value);
}
} else {
this.$message.warning(`获取钢卷列表失败:${response.msg || '未知错误'}`);
}
} catch (error) {
console.error('获取钢卷列表异常', error);
this.$message.error('获取钢卷列表失败,请重试');
} finally {
this.loading = false;
}
},
// 根据coilId匹配钢卷数据
matchCoilById(coilId) {
const matchedCoil = this.coilList.find(item => item.coilId == coilId);
if (matchedCoil) {
this.selectedCoil = matchedCoil;
}
},
// 触发器模式:打开对话框
handleOpen() {
this.innerVisible = true;
},
// 搜索
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
// 重置搜索条件
resetQuery() {
this.queryParams = {
pageNum: 1,
pageSize: 50,
currentCoilNo: null,
grade: null,
dataType: 1,
itemType: this.defaultType,
selectType: this.defaultType,
};
this.getList();
},
// 点击表格行选择 - 新增禁用行拦截
handleRowClick(row) {
if (this.disableO) {
// 并且钢卷的warehouseId不是1988150210872930306
// 1988150380649967617
// 1988150800092950529
// 1988151027466170370其中之一才不能选择
const warehouseIds = ['1988150210872930306', '1988150380649967617', '1988150800092950529', '1988151027466170370'];
// 如果没有判级就不能选择,除非是那分剪四个库区
if (!row.qualityStatus && !warehouseIds.includes(row.warehouseId)) {
this.$message.warning('未判级的钢卷不能选择');
return;
}
const disabledOList = ['O', 'C+', 'C', 'C-', 'D+', 'D', 'D-']
if (disabledOList.includes(row.qualityStatus)) {
this.$message.warning(`${row.qualityStatus}卷不能选择`);
return;
}
}
this.handleSelect(row);
},
// 选择钢卷(确认选择)
handleSelect(row) {
if (!row) {
this.$message.warning('请选择有效的钢卷数据');
return;
}
if (this.multiple) {
// 检查是否已经选择
if (this.selectedCoils.some(item => item.coilId === row.coilId)) {
// 再次点击删除
this.handleRemove(row);
return;
}
this.selectedCoils.push(row);
return;
// return;
} else {
this.selectedCoil = row;
}
// 触发自定义事件,通知父组件选中结果(返回完整行数据)
this.$emit('select', row);
// 触发器模式下支持v-model双向绑定
if (this.useTrigger) {
this.$emit('input', row.coilId);
this.$emit('change', row.coilId, row); // 兼容v-model的change事件
}
// 选择后关闭对话框
this.handleClose();
},
// 清除选中状态
handleClearSelection() {
this.selectedCoil = null;
this.selectedCoils = []; // 清空多选数据
this.$emit('input', '');
this.$emit('change', '', null); // 兼容v-model的change事件
this.$emit('clear', true); // 触发清除事件
},
// 关闭对话框
handleClose() {
this.dialogVisible = false;
this.$emit('close');
},
confirmColumnConfig() {
this.saveColumnConfig();
this.loadColumnConfig();
this.showColumnSetting = false;
},
loadColumnConfig() {
const storageKey = this.columnStorageKey;
const savedConfig = localStorage.getItem(storageKey);
if (savedConfig) {
try {
this.columnsConfig = JSON.parse(savedConfig);
} catch (e) {
console.error('解析列配置失败', e);
this.columnsConfig = this.orderBy ? [...fullPageDefaultColumns] : [...defaultColumns];
}
} else {
this.columnsConfig = this.orderBy ? [...fullPageDefaultColumns] : [...defaultColumns];
}
},
saveColumnConfig() {
const nonEmptyColumns = this.columnsConfig.filter(col => col.prop && col.label);
localStorage.setItem(this.columnStorageKey, JSON.stringify(nonEmptyColumns));
this.columnsConfigVersion++;
},
moveColumnUp(index) {
if (index > 0 && !this.displayColumns[index]._isEmpty) {
const temp = this.columnsConfig[index];
this.columnsConfig.splice(index, 1);
this.columnsConfig.splice(index - 1, 0, temp);
this.saveColumnConfig();
}
},
moveColumnDown(index) {
if (index < this.columnsConfig.length - 1 && !this.displayColumns[index]._isEmpty) {
const temp = this.columnsConfig[index];
this.columnsConfig.splice(index, 1);
this.columnsConfig.splice(index + 1, 0, temp);
this.saveColumnConfig();
}
},
removeColumn(index) {
if (!this.displayColumns[index]._isEmpty) {
this.columnsConfig.splice(index, 1);
this.saveColumnConfig();
}
},
columnPropChange(propValue, row) {
const item = optionalColumns.find(item => item.value === propValue);
if (item) {
row.label = item.label;
} else {
row.label = propValue;
}
if (row._isEmpty && propValue) {
const newColumn = {
label: row.label,
prop: row.prop,
width: row.width,
align: row.align,
showOverflowTooltip: true
};
this.columnsConfig.push(newColumn);
this.saveColumnConfig();
} else {
this.saveColumnConfig();
}
},
resetColumnConfig() {
this.columnsConfig = this.orderBy ? [...fullPageDefaultColumns] : [...defaultColumns];
this.saveColumnConfig();
}
}
};
</script>
<style scoped lang="scss">
.coil-selector-container {
width: 100%;
}
.trigger-container {
display: flex;
flex-direction: column;
gap: 8px;
}
.coil-selector-drag-panel {
flex: 1;
min-height: 0;
overflow: hidden;
box-sizing: border-box;
}
// 未选择状态样式
.no-selection {
padding: 8px 12px;
border: 1px dashed #dcdcdc;
border-radius: 4px;
color: #999;
background-color: #f9f9f9;
width: fit-content;
}
// 已选择状态样式
.selected-coil-info {
padding: 12px;
border: 1px solid #e6f7ff;
border-radius: 6px;
background-color: #f0f9ff;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 16px 24px;
width: fit-content;
max-width: 100%;
.info-item {
display: flex;
align-items: center;
gap: 6px;
.label {
color: #666;
font-size: 13px;
}
.value {
color: #333;
font-size: 14px;
font-weight: 500;
white-space: nowrap;
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
}
}
.clear-selection {
color: #f56c6c;
margin-left: 12px;
padding: 0 8px;
&:hover {
color: #ff4d4f;
background-color: transparent;
}
}
}
// 选择按钮样式
.select-button {
margin-top: 4px;
}
::v-deep .el-dialog__body {
padding: 0 !important;
max-height: calc(100vh - 200px);
min-height: 500px;
overflow-y: hidden !important;
box-sizing: border-box;
}
// panelA容器样式
.panel-a-container {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
// 表格容器样式
.table-wrapper {
flex: 1;
overflow: hidden;
}
// 分页容器样式
.pagination-wrapper {
flex-shrink: 0;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 10px;
padding-top: 10px;
}
// panelB容器样式
.panel-b-container {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
min-height: 0;
max-height: 100%;
box-sizing: border-box;
}
// 已选表格容器样式
.selected-table-wrapper {
flex: 1;
overflow-y: hidden;
overflow-x: hidden;
min-height: 0;
max-height: calc(100% - 30px);
box-sizing: border-box;
}
// 空面板样式
.empty-panel {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
padding: 20px;
}
::v-deep .el-table {
--el-table-row-hover-bg-color: var(--el-color-primary-light-9);
}
::v-deep .el-table__row.current-row {
background-color: var(--el-color-primary-light-8) !important;
}
// 核心:已选钢卷样式(黄色背景)
::v-deep .el-table .selected-coil-row {
background-color: #fffbe6 !important;
/* 浅黄色背景 */
&:hover>td {
background-color: #fff8d9 !important;
/* hover时稍深一点的黄色 */
}
// 当同时是当前行时
&.current-row {
background-color: #fff8d9 !important;
}
}
.dialog-footer {
text-align: right;
}
// 已选钢卷统计信息样式
.selected-stats {
display: flex;
justify-content: space-between;
align-items: center;
.stats-content {
display: flex;
gap: 24px;
.stat-item {
display: flex;
align-items: center;
gap: 8px;
.stat-label {
color: #666;
font-size: 14px;
}
.stat-value {
color: #333;
font-size: 16px;
font-weight: 600;
}
}
}
}
// 响应式调整
@media (max-width: 768px) {
.selected-coil-info {
gap: 12px;
padding: 10px;
}
.info-item {
flex: 1 1 calc(50% - 12px);
}
}
</style>