Files
klp-oa/klp-ui/src/components/KLPService/RawMaterialSelect/index.vue

369 lines
11 KiB
Vue
Raw Normal View History

2025-07-18 17:22:56 +08:00
<template>
<div class="raw-material-selector">
<!-- 触发器按钮 -->
<el-button
v-if="!readonly"
type="text"
:icon="multiple ? 'el-icon-checks' : 'el-icon-check'"
@click="dialogVisible = true"
>
{{ buttonText }}
</el-button>
<span v-else class="readonly-text">{{ displayText }}</span>
<!-- 选择对话框 -->
<el-dialog
title="选择原材料"
:visible.sync="dialogVisible"
width="1200px"
:close-on-click-modal="false"
@close="handleClose"
append-to-body
>
<!-- 搜索区域同步原料管理页面筛选字段 -->
<el-form :inline="true" :model="queryParams" class="search-form" size="small">
<el-form-item label="原材料编号">
<el-input
v-model="queryParams.rawMaterialCode"
placeholder="请输入原材料编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="原材料名称">
<el-input
v-model="queryParams.rawMaterialName"
placeholder="请输入原材料名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="规格">
<el-input
v-model="queryParams.specification"
placeholder="请输入规格"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="材质">
<el-input
v-model="queryParams.material"
placeholder="请输入材质"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="厂家">
<el-input
v-model="queryParams.manufacturer"
placeholder="请输入厂家"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="表面处理">
<el-input
v-model="queryParams.surfaceTreatmentDesc"
placeholder="请输入表面处理"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="锌层">
<el-input
v-model="queryParams.zincLayer"
placeholder="请输入锌层"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
2025-08-19 15:39:59 +08:00
</el-form>
<!-- 数据表格同步原料管理页面核心字段 -->
<el-table
ref="table"
v-loading="loading"
:data="rawMaterialList"
@row-click="handleRowClick"
@selection-change="handleSelectionChange"
:select-on-indeterminate="multiple"
highlight-current-row
height="400px"
style="width: 100%"
>
<el-table-column
type="selection"
width="55"
align="center"
v-if="multiple"
/>
<el-table-column label="原材料编号" align="center" prop="rawMaterialCode" :show-overflow-tooltip="true" />
<el-table-column label="原材料名称" align="center" prop="rawMaterialName" :show-overflow-tooltip="true" width="180" />
<el-table-column label="规格" align="center" prop="specification" width="120" />
<el-table-column label="计量单位" align="center" prop="unit" width="100" />
<el-table-column label="材质" align="center" prop="material" />
<el-table-column label="厂家" align="center" prop="manufacturer" width="120" :show-overflow-tooltip="true" />
<el-table-column label="表面处理" align="center" prop="surfaceTreatmentDesc" />
<el-table-column label="锌层" align="center" prop="zincLayer" width="80" />
<el-table-column label="操作" align="center" width="100">
<template slot-scope="scope">
<el-button type="text" size="small" @click.stop="handleSelect(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
2025-08-19 15:39:59 +08:00
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button
type="primary"
@click="confirmSelection"
v-if="multiple"
>
确认选择
</el-button>
</div>
</el-dialog>
</div>
2025-07-18 17:22:56 +08:00
</template>
<script>
// 替换为原材料接口
import { listRawMaterial } from '@/api/wms/rawMaterial';
2025-07-21 11:55:04 +08:00
2025-07-18 17:22:56 +08:00
export default {
name: 'RawMaterialSelector',
2025-07-18 17:22:56 +08:00
props: {
// 双向绑定值逗号分隔的rawMaterialId字符串
value: {
2025-07-18 17:22:56 +08:00
type: String,
default: ''
2025-08-19 15:39:59 +08:00
},
// 是否只读
readonly: {
2025-08-19 15:39:59 +08:00
type: Boolean,
default: false
},
// 是否允许多选
multiple: {
type: Boolean,
default: false
},
// 过滤条件(继承原料管理页面筛选逻辑)
filters: {
type: Object,
default: () => ({})
}
},
2025-07-18 17:22:56 +08:00
data() {
return {
dialogVisible: false,
2025-08-19 15:39:59 +08:00
loading: false,
rawMaterialList: [], // 原材料列表数据
total: 0,
// 查询参数(同步原料管理页面核心筛选字段)
queryParams: {
pageNum: 1,
pageSize: 10,
rawMaterialCode: undefined,
rawMaterialName: undefined,
specification: undefined,
material: undefined,
manufacturer: undefined,
surfaceTreatmentDesc: undefined,
zincLayer: undefined
2025-08-19 15:39:59 +08:00
},
// 内部选中的原材料ID数组关联rawMaterialId
selectedIds: [],
// 内部选中的行数据
selectedRows: []
2025-07-18 17:22:56 +08:00
};
},
computed: {
// 按钮显示文本
buttonText() {
if (this.multiple) {
return this.selectedIds.length > 0
? `已选 ${this.selectedIds.length}`
: '选择原材料';
} else {
return this.selectedRows[0]?.rawMaterialName || '选择原材料';
}
2025-07-21 10:56:50 +08:00
},
// 只读状态显示文本
displayText() {
if (this.multiple) {
return this.selectedIds.length > 0
? `已选 ${this.selectedIds.length}`
: '未选择';
} else {
return this.selectedRows[0]?.rawMaterialName || '未选择';
}
2025-07-18 17:22:56 +08:00
}
},
watch: {
// 监听外部值变化,同步到内部选中状态
value: {
immediate: true,
handler(val) {
this.selectedIds = val ? val.split(',').filter(id => id) : [];
// 列表已加载时同步表格选中状态
if (this.rawMaterialList.length > 0) {
this.syncTableSelection();
}
}
},
// 监听对话框显示,加载原材料列表
dialogVisible(val) {
if (val) {
this.getList().then(() => {
this.syncTableSelection();
});
}
2025-08-23 17:22:06 +08:00
}
2025-07-30 10:53:06 +08:00
},
2025-07-18 17:22:56 +08:00
methods: {
// 获取原材料列表(调用原料接口)
async getList() {
try {
this.loading = true;
const params = { ...this.queryParams, ...this.filters };
const response = await listRawMaterial(params);
if (response.code === 200) {
this.rawMaterialList = response.rows || [];
this.total = response.total || 0;
}
return this.rawMaterialList;
} catch (error) {
console.error('获取原材料列表失败', error);
this.$message.error('获取原材料列表失败');
} finally {
this.loading = false;
}
},
// 搜索(逻辑不变,同步筛选参数)
handleQuery() {
this.queryParams.pageNum = 1;
this.getList().then(() => {
this.syncTableSelection();
});
},
// 重置(重置为原材料查询参数)
resetQuery() {
this.queryParams = {
pageNum: 1,
pageSize: 10,
rawMaterialCode: undefined,
rawMaterialName: undefined,
specification: undefined,
material: undefined,
manufacturer: undefined,
surfaceTreatmentDesc: undefined,
zincLayer: undefined
2025-08-19 15:39:59 +08:00
};
this.getList().then(() => {
this.syncTableSelection();
});
2025-08-19 15:39:59 +08:00
},
// 行点击事件(单选直接确认)
handleRowClick(row) {
if (!this.multiple) {
this.selectedIds = [row.rawMaterialId];
this.selectedRows = [row];
this.confirmSelection();
}
},
// 选择项变化(多选)
handleSelectionChange(rows) {
this.selectedRows = rows;
this.selectedIds = rows.map(row => row.rawMaterialId);
},
// 单个选择按钮(多选切换选中状态,单选直接确认)
handleSelect(row) {
if (this.multiple) {
const index = this.selectedIds.indexOf(row.rawMaterialId);
index > -1
? (this.selectedIds.splice(index, 1), this.selectedRows.splice(index, 1))
: (this.selectedIds.push(row.rawMaterialId), this.selectedRows.push(row));
this.syncTableSelection();
} else {
this.selectedIds = [row.rawMaterialId];
this.selectedRows = [row];
this.confirmSelection();
}
2025-08-19 15:39:59 +08:00
},
// 同步表格选中状态
syncTableSelection() {
this.$nextTick(() => {
if (this.multiple && this.$refs.table) {
this.rawMaterialList.forEach(row => {
const isSelected = this.selectedIds.includes(row.rawMaterialId);
this.$refs.table.toggleRowSelection(row, isSelected);
2025-08-19 15:39:59 +08:00
});
}
});
},
// 确认选择触发v-model更新和change事件
confirmSelection() {
const emitValue = this.selectedIds.join(',');
this.$emit('input', emitValue);
this.$emit('change', emitValue, this.selectedRows);
this.dialogVisible = false;
},
// 关闭对话框(恢复原始选中状态)
handleClose() {
this.selectedIds = this.value ? this.value.split(',').filter(id => id) : [];
this.dialogVisible = false;
2025-08-19 15:39:59 +08:00
}
2025-07-18 17:22:56 +08:00
}
};
</script>
2025-07-21 10:56:50 +08:00
<style scoped lang="scss">
.raw-material-selector {
display: inline-block;
}
.search-form {
margin-bottom: 20px;
flex-wrap: wrap; // 适配多筛选字段换行
}
.readonly-text {
color: #606266;
line-height: 1;
padding: 8px 0;
display: inline-block;
2025-07-21 10:56:50 +08:00
}
2025-08-19 15:39:59 +08:00
::v-deep .el-dialog__body {
padding: 20px;
overflow-x: auto; // 适配宽表格横向滚动
2025-07-21 10:56:50 +08:00
}
2025-08-19 15:39:59 +08:00
::v-deep .el-form-item {
margin-bottom: 15px;
margin-right: 15px;
2025-07-21 10:56:50 +08:00
}
</style>