Files
zhongxinmes-IMPM-UI/src/views/mes/wm/productrecpt/line.vue
2025-08-22 14:24:18 +08:00

676 lines
20 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

/* 2024 12 16 新增props:"upFlag",用于更新父组件表单数据
新增props:"warehouseInfo",用于获取仓库信息 */
<template>
<div class="app-container">
<el-row v-if="optType != 'view'" :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['mes:wm:productrecpt:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-if="optType != 'view'"
v-hasPermi="['mes:wm:productrecpt:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-if="optType != 'view'"
v-hasPermi="['mes:wm:productrecpt:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-upload2"
size="mini"
@click="handleImport"
v-if="optType != 'view'"
v-hasPermi="['mes:wm:productrecpt:add']"
>导入</el-button
>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="productrecptlineList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" fixed="left" />
<el-table-column
label="产品物料编码"
width="120px"
align="center"
prop="itemCode"
/>
<el-table-column
label="产品物料名称"
width="150px"
align="center"
prop="itemName"
:show-overflow-tooltip="true"
/>
<el-table-column
label="规格型号"
width="120px"
align="center"
prop="specification"
:show-overflow-tooltip="true"
/>
<el-table-column label="单位" align="center" prop="unitOfMeasure" />
<el-table-column label="入库数量" align="center" prop="quantityRecived" />
<el-table-column label="批次号" align="center" prop="batchCode" />
<el-table-column label="仓库名称" align="center" prop="warehouseName" />
<el-table-column label="库区名称" align="center" prop="locationName" />
<el-table-column label="库位名称" align="center" prop="areaName" />
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
fixed="right"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-if="optType != 'view'"
v-hasPermi="['mes:wm:productrecpt:edit']"
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-if="optType != 'view'"
v-hasPermi="['mes:wm:productrecpt:remove']"
>删除</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"
/>
<!-- 添加或修改产品入库记录行对话框 -->
<el-dialog :title="title" :visible.sync="open" width="960px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="8">
<el-form-item label="产品物料编码" prop="itemCode">
<el-input v-model="form.itemCode" placeholder="请输入产品物料编码" readonly>
<el-button
slot="append"
@click="handleSelectProduct"
icon="el-icon-search"
v-if="title === '添加产品入库记录行'"
></el-button>
</el-input>
<ItemSelect ref="itemSelect" @onSelected="onItemSelected"> </ItemSelect>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="产品物料名称" prop="itemName">
<el-input
v-model="form.itemName"
placeholder="请输入产品物料名称"
readonly
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="单位" prop="unitOfMeasure">
<el-input v-model="form.unitOfMeasure" placeholder="请输入单位" readonly />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="规格型号" prop="specification">
<el-input v-model="form.specification" placeholder="请输入内容" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="入库重量" prop="quantityRecived">
<el-input-number
:min="0.01"
:max="form.quantityMax"
v-model="form.quantityRecived"
placeholder="请输入入库数量"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="批次号" prop="batchCode">
<el-input v-model="form.batchCode" placeholder="请输入批次号" />
</el-form-item>
</el-col>
</el-row>
<!-- 2024 12 13 需求一 -->
<!-- <el-row>
<el-col :span="8">
<el-form-item label="入库仓库" prop="warehouseId">
<el-cascader v-model="warehouseInfo"
:options="warehouseOptions"
:props="warehouseProps"
@change="handleWarehouseChanged"
>
</el-cascader>
</el-form-item>
</el-col>
</el-row> -->
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 导入xlsx 对话框 -->
<el-dialog
title="数据导入"
:visible.sync="ImprotXlsxFlag"
width="600px"
append-to-body
>
<div style="display: flex; justify-content: center; align-items: center">
<el-upload
class="upload-demo"
drag
action=""
:multiple="false"
accept=".xlsx,.xls"
:auto-upload="false"
:show-file-list="true"
:file-list="xlsxFile"
:on-change="handleXlsxChange"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击导入</em></div>
<div class="el-upload__tip" slot="tip">
只能上传.xlsx/.xls文件并且确保您的文档内容符合规范
</div>
</el-upload>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitXlsx" :disabled="!(ProAllArr.length > 0)"
> </el-button
>
<el-button @click="cancelXlsx"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listProductrecptline,
getProductrecptline,
delProductrecptline,
addProductrecptline,
updateProductrecptline,
} from "@/api/mes/wm/productrecptline";
import StockSelect from "@/components/stockSelect/single.vue";
import { getTreeList } from "@/api/mes/wm/warehouse";
import ItemSelect from "@/components/itemSelect/single.vue";
// 引入xlsx
import * as XLSX from "xlsx";
// 引入lodash
import { cloneDeep } from "lodash";
// utils
import { ImportXlsxTransformFn } from "./utils/utils";
export default {
name: "Productrecptline",
components: {
StockSelect,
ItemSelect
},
props: {
recptId: null,
optType: null,
workorderId: null,
itemId: null,
item: {},
warehouseInfo: null,
upFlag: Boolean,
},
data() {
return {
// 并发请求所用的请求参数数组
ProAllArr: [],
// xlsx默认文件
xlsxFile: [],
// 导入xlsx对话框开关
ImprotXlsxFlag: false,
// 防抖 防止频繁触发父组件更新 节省不必要的性能开销
timer: null,
// 2024 12 16 需求一 props存在同名声明 且props优先级高于data
// warehouseInfo:[],
warehouseOptions: [],
warehouseProps: {
multiple: false,
value: "pId",
label: "pName",
},
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 产品入库记录行表格数据
productrecptlineList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
recptId: this.recptId,
materialStockId: null,
itemId: null,
itemCode: null,
itemName: null,
specification: null,
unitOfMeasure: null,
quantityRecived: null,
batchCode: null,
warehouseId: null,
warehouseCode: null,
warehouseName: null,
locationId: null,
locationCode: null,
locationName: null,
areaId: null,
areaCode: null,
areaName: null,
},
// 表单参数
form: {},
// 表单校验
rules: {
itemId: [{ required: true, message: "产品不能为空", trigger: "blur" }],
warehouseId: [{ required: true, message: "入库仓库不能为空", trigger: "blur" }],
quantityRecived: [
{ required: true, message: "入库数量不能为空", trigger: "blur" },
],
},
};
},
created() {
this.getList();
this.getWarehouseList();
},
methods: {
// 发送并发请求 根据导入的xlsx文件批量新增数据
// 若并发请求成功 做出提示 关闭所有弹窗 清空文件列表和并发参数数据 重新加载列表数据
submitXlsx() {
console.log("submitXlsx");
if (this.ProAllArr.length == 0) return;
Promise.all(this.ProAllArr.map((item) => addProductrecptline(item)))
.then((res) => {
console.log("✅", res);
this.$modal.msgSuccess("数据导入成功");
this.open = false;
this.ImprotXlsxFlag = false;
// 清空文件列表
this.xlsxFile = [];
// 清空并发请求参数数据
this.ProAllArr = [];
this.getList();
})
.catch((err) => {
console.log("❎", err);
this.$modal.msgError("数据导入失败,请稍后重试!");
});
},
// 关闭 导入xlsx的弹窗
cancelXlsx() {
this.ImprotXlsxFlag = false;
// 清空文件列表
this.xlsxFile = [];
// 清空并发请求参数数据
this.ProAllArr = [];
},
// 2024 12 17 需求三 导入xlsx文件
// 监听文件列表改变
handleXlsxChange(file, fileList) {
let oldObj = cloneDeep(this.form);
var that = this;
function handleFileUpload(event) {
const file = event.raw;
const reader = new FileReader();
reader.onload = (e) => {
const data = new Uint8Array(e.target.result);
const workbook = XLSX.read(data, { type: "array" });
// 获取第一个工作表
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
// 转换为 JSON 数据
const jsonData = XLSX.utils.sheet_to_json(worksheet);
// 转换前校验
let CheckResults = jsonData.every((item) => {
return Object.keys(item).includes("入库重量");
});
if (!CheckResults) {
that.$modal.msgError(
"文件内容不符合要求,请检查后重新上传!(至少一列有【入库重量】字段)"
);
that.xlsxFile = [];
return;
}
// console.log("TransformFn➡", TransformFn(jsonData, oldObj));
// 处理数据
that.ProAllArr = ImportXlsxTransformFn(jsonData, oldObj);
};
reader.readAsArrayBuffer(file);
}
handleFileUpload(file);
// handleFileUpload.call(this, file);
},
// 2024 12 16 需求三 导入数据
handleImport() {
console.log("开始执行导入xlsx逻辑⬇");
this.handleAddInitiative();
this.ImprotXlsxFlag = true;
},
// 2024 12 16 需求二 用于更新 "合计重量"
handleChangeUpFlag() {
// console.log("Try:1");
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
this.$emit("changeUpFlag", this.upFlag);
}, 500);
},
/** 查询产品入库记录行列表 */
getList() {
this.loading = true;
listProductrecptline(this.queryParams).then((response) => {
this.productrecptlineList = response.rows;
this.total = response.total;
this.loading = false;
});
},
getWarehouseList() {
getTreeList().then((response) => {
this.warehouseOptions = response.data;
this.warehouseOptions.map((w) => {
w.children.map((l) => {
let lstr = JSON.stringify(l.children)
.replace(/locationId/g, "lId")
.replace(/areaId/g, "pId")
.replace(/areaName/g, "pName");
l.children = JSON.parse(lstr);
});
let wstr = JSON.stringify(w.children)
.replace(/warehouseId/g, "wId")
.replace(/locationId/g, "pId")
.replace(/locationName/g, "pName");
w.children = JSON.parse(wstr);
});
let ostr = JSON.stringify(this.warehouseOptions)
.replace(/warehouseId/g, "pId")
.replace(/warehouseName/g, "pName");
this.warehouseOptions = JSON.parse(ostr);
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
lineId: null,
recptId: this.recptId,
materialStockId: null,
itemId: null,
itemCode: null,
itemName: null,
specification: null,
unitOfMeasure: null,
quantityRecived: null,
batchCode: null,
warehouseId: null,
warehouseCode: null,
warehouseName: null,
locationId: null,
locationCode: null,
locationName: null,
areaId: null,
areaCode: null,
areaName: null,
remark: null,
attr1: null,
attr2: null,
attr3: null,
attr4: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.lineId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
// 2024 12 13 需求一
handleAdd() {
this.reset();
// 注意执行顺序 重置 -> 赋值
this.handleWarehouseChanged(this.warehouseInfo);
this.form.itemId = this.item.itemId;
this.form.itemCode = this.item.itemCode;
this.form.itemName = this.item.itemName;
this.form.specification = this.item.specification;
this.form.unitOfMeasure = this.item.unitOfMeasure;
this.open = true;
this.title = "添加产品入库记录行";
},
// 2024 12 17 需求三
handleAddInitiative() {
this.reset();
// 注意执行顺序 重置 -> 赋值
this.handleWarehouseChanged(this.warehouseInfo);
this.form.itemId = this.item.itemId;
this.form.itemCode = this.item.itemCode;
this.form.itemName = this.item.itemName;
this.form.specification = this.item.specification;
this.form.unitOfMeasure = this.item.unitOfMeasure;
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const lineId = row.lineId || this.ids;
getProductrecptline(lineId).then((response) => {
this.form = response.data;
this.open = true;
this.title = "修改产品入库记录行";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
console.log("校验表单数据,意在入库➡️", this.form);
if (this.form.lineId != null) {
updateProductrecptline(this.form).then((response) => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
// 2024 12 17 标记
addProductrecptline(this.form).then((response) => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const lineIds = row.lineId || this.ids;
this.$modal
.confirm('是否确认删除产品入库记录行编号为"' + lineIds + '"的数据项?')
.then(function () {
return delProductrecptline(lineIds);
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download(
"mes/wm/productrecptline/export",
{
...this.queryParams,
},
`productrecptline_${new Date().getTime()}.xlsx`
);
},
handleSelectStock() {
this.$refs.stockSelect.showFlag = true;
this.$refs.stockSelect.getList();
},
//物料选择弹出框
onStockSelected(obj) {
if (obj != undefined && obj != null) {
this.form.materialStockId = obj.materialStockId;
this.form.itemId = obj.itemId;
this.form.itemCode = obj.itemCode;
this.form.itemName = obj.itemName;
this.form.specification = obj.specification;
this.form.unitOfMeasure = obj.unitOfMeasure;
this.form.batchCode = obj.batchCode;
this.form.quantityRecived = obj.quantityOnhand;
this.form.quantityMax = obj.quantityOnhand;
}
},
//选择默认的仓库、库区、库位
// 2024 12 13 需求一 标记点
handleWarehouseChanged(obj) {
console.log("handleWarehouseChanged➡", obj[0], obj[1], obj[2]);
if (obj != null) {
this.form.warehouseId = obj[0];
this.form.locationId = obj[1];
this.form.areaId = obj[2];
}
},
//物料选择弹出框
handleSelectProduct() {
this.$refs.itemSelect.showFlag = true;
},
//物料选择弹出框
onItemSelected(obj) {
if (obj != undefined && obj != null) {
this.form.itemId = obj.itemId;
this.form.itemCode = obj.itemCode;
this.form.itemName = obj.itemName;
this.form.specification = obj.specification;
this.form.unitOfMeasure = obj.unitOfMeasure;
}
},
},
beforeUpdate() {
console.log(
"beforeUpdate ➡️ 子组件"
// this.recptId,
// this.optType,
// this.workorderId,
// this.itemId,
// this.item,
// this.warehouseInfo
);
this.handleChangeUpFlag();
},
};
</script>