<template>
|
<div>
|
<vol-box
|
v-model="showDetialBox"
|
:lazy="true"
|
width="1300px"
|
height="700px"
|
:padding="20"
|
title="添加成品超期报废明细"
|
>
|
<div style="max-height: 700px; overflow-y: auto;">
|
<el-form ref="form" :model="form" label-width="130px">
|
<!-- 仓库选择 -->
|
<el-form-item required label="所属仓库:">
|
<el-select
|
v-model="form.warehouseId"
|
filterable
|
placeholder="请选择仓库"
|
@change="handleWarehouseChange"
|
style="width: 100%;"
|
>
|
<el-option
|
v-for="item in warehouses"
|
:key="item.key"
|
:label="item.value"
|
:value="item.key"
|
>
|
<span style="float: left">{{ item.value }}</span>
|
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.key }}</span>
|
</el-option>
|
</el-select>
|
</el-form-item>
|
|
<!-- 单据编号(只读) -->
|
<el-form-item required label="单据编号:">
|
<el-input
|
v-model="form.proScrapSheetOrderNo"
|
placeholder="系统将自动生成"
|
readonly
|
style="width: 100%;"
|
></el-input>
|
</el-form-item>
|
|
<!-- 明细列表 -->
|
<el-form-item label="报废明细:">
|
<div v-for="(detail, index) in detailList" :key="index" class="detail-item">
|
<div class="detail-header">
|
<span>明细 {{ index + 1 }}</span>
|
<el-button
|
type="text"
|
size="mini"
|
color="#f56c6c"
|
@click="removeDetail(index)"
|
:disabled="detailList.length <= 1"
|
>
|
删除
|
</el-button>
|
</div>
|
|
<el-row :gutter="20" class="detail-row">
|
<el-col :span="6">
|
<el-form-item
|
required
|
label="产品编码:"
|
>
|
<el-select
|
v-model="detail.scrapProCode"
|
filterable
|
placeholder="产品编码"
|
@change="handleProCodeChange(detail, index)"
|
clearable
|
style="width: 100%;"
|
>
|
<el-option
|
v-for="(code, idx) in proCodeOptions"
|
:key="idx"
|
:label="code"
|
:value="code"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
|
<el-col :span="5">
|
<el-form-item
|
required
|
label="版本:"
|
>
|
<el-select
|
v-model="detail.scrapProVersion"
|
filterable
|
placeholder="版本"
|
clearable
|
style="width: 100%;"
|
>
|
<el-option
|
v-for="item in detail.versionOptions"
|
:key="item"
|
:label="item"
|
:value="item"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
|
<el-col :span="5">
|
<el-form-item
|
required
|
label="批次号:"
|
>
|
<el-select
|
v-model="detail.scrapProLotNo"
|
filterable
|
placeholder="批次号"
|
clearable
|
style="width: 100%;"
|
>
|
<el-option
|
v-for="item in detail.lotNoOptions"
|
:key="item"
|
:label="item"
|
:value="item"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
|
<el-col :span="4">
|
<el-form-item
|
required
|
label="PCS数量:"
|
>
|
<el-input
|
v-model="detail.scrapPcsQty"
|
placeholder="PCS数量"
|
style="width: 100%;"
|
@blur="formatNumber(detail, 'scrapPcsQty')"
|
></el-input>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="20" class="detail-row">
|
<el-col :span="24">
|
<el-form-item label="备注:">
|
<el-input
|
v-model="detail.remark"
|
placeholder="请输入备注信息"
|
type="textarea"
|
rows="2"
|
style="width: 100%;"
|
></el-input>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</div>
|
|
<!-- 添加明细按钮 -->
|
<el-button
|
type="dashed"
|
size="small"
|
class="add-detail-btn"
|
@click="addDetail"
|
:disabled="detailList.length >= 10"
|
style="width: 100%; margin-top: 15px;"
|
>
|
<i class="el-icon-plus"></i> 添加明细
|
</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
|
<!-- 底部按钮 -->
|
<template #footer>
|
<el-button type="primary" size="mini" @click="submitForm" style="padding: 8px 20px;">确认提交</el-button>
|
<el-button type="danger" size="mini" @click="close" style="padding: 8px 20px; margin-left: 10px;">关闭</el-button>
|
</template>
|
</vol-box>
|
</div>
|
</template>
|
|
<script>
|
import VolBox from "@/components/basic/VolBox.vue";
|
export default {
|
components: { VolBox },
|
data() {
|
return {
|
showDetialBox: false,
|
warehouses: [],
|
proCodeOptions: [],
|
form: {
|
warehouseId: "",
|
proScrapSheetOrderNo: ""
|
},
|
detailList: [
|
{
|
scrapProCode: "",
|
scrapProVersion: "",
|
scrapProLotNo: "",
|
scrapPcsQty: "",
|
remark: "",
|
versionOptions: [],
|
lotNoOptions: []
|
}
|
]
|
};
|
},
|
methods: {
|
// 打开弹窗
|
open() {
|
this.initForm();
|
this.showDetialBox = true;
|
},
|
|
// 初始化表单
|
initForm() {
|
this.form = {
|
warehouseId: "",
|
proScrapSheetOrderNo: ""
|
};
|
this.proCodeOptions = []; // 清空产品编码列表
|
this.detailList = [this.createEmptyDetail()];
|
|
// 加载仓库列表
|
if (this.warehouses.length === 0) {
|
this.getWarehouseList();
|
}
|
},
|
|
// 创建空明细
|
createEmptyDetail() {
|
return {
|
scrapProCode: "",
|
scrapProVersion: "",
|
scrapProLotNo: "",
|
scrapPcsQty: "",
|
remark: "",
|
versionOptions: [],
|
lotNoOptions: []
|
};
|
},
|
|
// 获取仓库列表
|
getWarehouseList() {
|
this.http
|
.post("api/Warehouse/GetWarehouseDicByUser", null, "加载仓库数据中")
|
.then((res) => {
|
if (!res.status) return this.$message.error(res.message);
|
this.warehouses = res.data || [];
|
// 若只有一个仓库,自动选中
|
if (this.warehouses.length === 1) {
|
this.form.warehouseId = this.warehouses[0].key;
|
this.handleWarehouseChange(this.warehouses[0].key);
|
}
|
});
|
},
|
|
// 仓库变更事件
|
handleWarehouseChange(warehouseId) {
|
if (!warehouseId) {
|
this.proCodeOptions = []; // 仓库为空时清空产品编码列表
|
return;
|
}
|
// 根据仓库ID加载产品编码列表
|
this.http
|
.post(`api/ProStockInfo/GetProCodeByWarehouse?warehouseId=${warehouseId}`,null, "加载产品数据中")
|
.then((res) => {
|
if (res.status) {
|
this.proCodeOptions = [...new Set(res.data)];
|
} else {
|
this.$message.error(res.message);
|
}
|
});
|
},
|
|
// 产品编码变更事件
|
handleProCodeChange(detail, index) {
|
// 清空版本和批次号
|
detail.versionOptions = [];
|
detail.lotNoOptions = [];
|
detail.scrapProVersion = "";
|
detail.scrapProLotNo = "";
|
|
if (!detail.scrapProCode) {
|
return;
|
}
|
|
// 根据产品编码加载版本列表
|
this.http
|
.post(
|
`api/ProStockInfo/GetProVersionByCode?scrapProCode=${detail.scrapProCode}&warehouseId=${this.form.warehouseId}`,null, "加载版本数据中")
|
.then((res) => {
|
if (res.status) {
|
detail.versionOptions = [...new Set(res.data)];
|
}
|
});
|
|
// 根据产品编码加载批次号列表
|
this.http
|
.post(`api/ProStockInfo/GetProLotNoByCode?scrapProCode=${detail.scrapProCode}&warehouseId=${this.form.warehouseId}`,null, "加载批次数据中")
|
.then((res) => {
|
if (res.status) {
|
detail.lotNoOptions = [...new Set(res.data)];
|
}
|
});
|
},
|
|
formatNumber(detail, field) {
|
if (!detail[field]) return;
|
|
let value = detail[field].replace(/[^0-9.]/g, '');
|
|
const decimalIndex = value.indexOf('.');
|
if (decimalIndex !== -1) {
|
value = value.substring(0, decimalIndex + 1) + value.substring(decimalIndex + 1).replace(/\./g, '');
|
}
|
|
const parts = value.split('.');
|
if (parts.length > 1 && parts[1].length > 2) {
|
parts[1] = parts[1].substring(0, 2);
|
value = parts.join('.');
|
}
|
|
detail[field] = value;
|
},
|
|
// 添加明细
|
addDetail() {
|
this.detailList.push(this.createEmptyDetail());
|
},
|
|
// 删除明细
|
removeDetail(index) {
|
this.detailList.splice(index, 1);
|
},
|
|
// 提交表单
|
submitForm() {
|
// 自定义验证逻辑
|
let isValid = true;
|
let errorMessage = '';
|
|
// 验证仓库
|
if (!this.form.warehouseId) {
|
isValid = false;
|
errorMessage = '请选择所属仓库';
|
}
|
|
// 验证明细
|
if (isValid) {
|
const invalidDetail = this.detailList.find(item =>
|
!item.scrapProCode ||
|
!item.scrapProVersion ||
|
!item.scrapProLotNo ||
|
!item.scrapPcsQty ||
|
isNaN(parseFloat(item.scrapPcsQty)) ||
|
parseFloat(item.scrapPcsQty) <= 0
|
);
|
|
if (invalidDetail) {
|
isValid = false;
|
errorMessage = '提交数据存在空值或输入数量不合法,请检查!';
|
}
|
}
|
|
// 根据验证结果处理
|
if (!isValid) {
|
this.$message.error(errorMessage);
|
return;
|
}
|
|
// 验证通过,准备提交数据
|
const submitData = {
|
warehouseId: this.form.warehouseId,
|
details: this.detailList.map(item => ({
|
scrapProCode: item.scrapProCode,
|
scrapProVersion: item.scrapProVersion,
|
scrapProLotNo: item.scrapProLotNo,
|
scrapPcsQty: parseFloat(item.scrapPcsQty),
|
remark: item.remark
|
}))
|
};
|
|
this.http
|
.post("api/ErpProScrapSheet/Save", submitData, "提交中")
|
.then((res) => {
|
if (!res.status) return this.$message.error(res.message);
|
this.$message.success("操作成功");
|
this.proCodeOptions = [];
|
this.close();
|
this.$emit("parentCall", ($vue) => {
|
$vue.refresh();
|
});
|
});
|
},
|
|
// 关闭弹窗
|
close() {
|
this.showDetialBox = false;
|
// 清空产品编码列表
|
this.proCodeOptions = [];
|
}
|
},
|
created() {
|
// 初始化时预加载仓库数据
|
if (this.warehouses.length === 0) {
|
this.getWarehouseList();
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.detail-item {
|
border: 1px solid #e4e7ed;
|
border-radius: 6px;
|
padding: 15px;
|
margin-bottom: 20px;
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
}
|
|
.detail-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 15px;
|
padding-bottom: 10px;
|
border-bottom: 1px dashed #e4e7ed;
|
font-weight: 500;
|
}
|
|
.detail-row {
|
margin-bottom: 15px;
|
}
|
|
.add-detail-btn {
|
height: 40px;
|
line-height: 38px;
|
}
|
|
::-webkit-scrollbar {
|
width: 8px;
|
height: 8px;
|
}
|
::-webkit-scrollbar-thumb {
|
background-color: #ddd;
|
border-radius: 4px;
|
}
|
::-webkit-scrollbar-track {
|
background-color: #f5f5f5;
|
}
|
|
/* 增加选择框的长度 */
|
.el-select {
|
width: 100% !important;
|
min-width: 150px !important;
|
padding-right:10px;
|
}
|
.el-input {
|
width: 100% !important;
|
min-width: 150px !important;
|
padding-right:10px;
|
}
|
|
</style>
|