空管耐用品库存管理前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

941 lines
31 KiB

<template>
<div>
<el-dialog
:close-on-click-modal="false"
:title="inDialogTiltle"
:visible.sync="inDialogVisible"
:append-to-body="true"
width="70%"
@close="handleCloseDetail"
fullscreen
class="dialog-container"
>
<!-- 基本信息 -->
<div class="dialog-content">
<el-form
:model="sizeForm"
ref="dynamicValidateForm"
label-width="100px"
class="demo-dynamic"
:rules="rules"
>
<div class="form-title">基本信息</div>
<el-row>
<el-col
:span="12"
v-show="sizeForm.options == 1 && inDialogType != 'add'"
>
<el-form-item label="入库单号">
<el-input v-model="sizeForm.orderNo" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入库时间">
<el-date-picker
v-model="sizeForm.inDate"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
type="date"
placeholder="选择日期"
style="width: 100%"
disabled
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="事由">
<el-input
v-model="sizeForm.reason"
:disabled="inDialogType == 'details'"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物资类型">
<el-select
v-model="sizeForm.materialType"
placeholder="请选择"
style="width: 100%"
:disabled="inDialogType == 'details'"
>
<el-option label="办公物资" value="1"></el-option>
<el-option label="其他物资" value="2"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="source" label="来源">
<el-select
v-model="sizeForm.source"
placeholder="请选择"
style="width: 100%"
:disabled="inDialogType == 'details'"
>
<el-option label="采购申请" value="cg"></el-option>
<el-option label="其他来源" value="qt"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="选项">
<el-radio-group
v-model="sizeForm.option"
@change="radioChange()"
:disabled="inDialogType == 'details'"
>
<el-radio :label="1">批量选择</el-radio>
<el-radio :label="2">单项选择</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="sizeForm.option == 1">
<el-form-item label="采购单名称">
<el-input v-model="sizeForm.quarterName" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<div class="form-title">{{ inDate }}</div>
<el-button
type="primary"
size="mini"
style="margin-bottom: 18px"
@click="inTableAdd()"
v-if="!allDisabled && sizeForm.option == 2"
>新增</el-button
>
<!-- 批量选择 -->
<el-table
:data="sizeForm.inTableData"
border
style="width: 100%"
v-show="sizeForm.option == 1"
>
<el-table-column
prop="inboundDetailCode"
label="入库明细单号"
v-if="inDialogType == 'details'"
>
</el-table-column>
<el-table-column prop="materialCode" label="物资编码">
</el-table-column>
<el-table-column prop="materialName" label="物资名称">
</el-table-column>
<el-table-column prop="model" label="规格"> </el-table-column>
<el-table-column prop="unit" label="单位"> </el-table-column>
<el-table-column prop="type" label="类别">
<template slot-scope="scope">
<el-select
v-model="scope.row.type"
placeholder="请选择"
style="width: 100%"
:disabled="inDialogType == 'details'"
@change="handleTypeChange(scope.row)"
v-if="inDialogType != 'details'"
>
<el-option label="耐用品" value="NY"></el-option>
<el-option label="易耗品" value="YH"></el-option>
</el-select>
<span v-else>{{
scope.row.type == "NY" ? "耐用品" : "易耗品"
}}</span>
</template>
</el-table-column>
<el-table-column
prop="requiredQuantity"
label="计划采购数量"
v-if="sizeForm.option == 1"
>
<template slot-scope="scope">
{{ scope.row.requiredQuantity || 0 }}
</template>
</el-table-column>
<el-table-column
prop="yetInboundQuantity"
label="已入库数量"
v-if="sizeForm.option == 1"
>
</el-table-column>
<el-table-column prop="theInboundQuantity" label="本次入库数量">
<template slot-scope="scope">
<el-input-number
size="mini"
v-model="scope.row.theInboundQuantity"
:min="0"
style="width: 100%"
@change="syncInboundQuantity(scope.row)"
v-if="inDialogType != 'details'"
></el-input-number>
<span v-else>{{
scope.row.theInboundQuantity === undefined
? 0
: scope.row.theInboundQuantity
}}</span>
</template>
</el-table-column>
<el-table-column prop="unitPrice" label="单价">
<template slot-scope="scope">
<el-input-number
size="mini"
v-model="scope.row.unitPrice"
:min="0"
style="width: 100%"
@change="syncUnitPrice(scope.row)"
v-if="inDialogType != 'details' && scope.row.type !== 'YH'"
></el-input-number>
<span v-else-if="scope.row.type === 'YH'">-</span>
<span v-else>{{ scope.row.unitPrice || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注">
<template slot-scope="scope">
<el-input
v-model="scope.row.remark"
placeholder="请输入备注"
v-if="inDialogType != 'details'"
></el-input>
<span v-else>{{ scope.row.remark }}</span>
</template>
</el-table-column>
</el-table>
<!-- 单项选择 -->
<el-table
:data="sizeForm.singleData"
border
style="width: 100%"
v-show="sizeForm.option == 2"
align="center"
>
<el-table-column
prop="inboundDetailCode"
label="入库明细单号"
v-if="inDialogType == 'details'"
>
</el-table-column>
<el-table-column
prop="materialCode"
label="物资编码"
></el-table-column>
<el-table-column prop="materialName" label="物资名称">
<template slot-scope="scope">
<el-select
v-model="scope.row.materialId"
placeholder="请选择物资名称"
style="width: 100%"
@change="handleMaterialChange(scope.row)"
v-if="inDialogType != 'details'"
>
<el-option
v-for="item in materials"
:key="item.materialId"
:label="item.materialName"
:value="item.materialId"
>
</el-option>
</el-select>
<span v-else> {{ scope.row.materialName }}</span>
</template>
</el-table-column>
<el-table-column prop="model" label="物资规格"></el-table-column>
<el-table-column prop="type" label="类别 ">
<template slot-scope="scope">
<el-select
v-model="scope.row.type"
placeholder="请选择"
style="width: 100%"
@change="handleTypeChange(scope.row)"
v-if="inDialogType !== 'details'"
>
<el-option label="耐用品" value="NY"></el-option>
<el-option label="易耗品" value="YH"></el-option>
</el-select>
<span v-else>{{
scope.row.type == "NY" ? "耐用品" : "易耗品"
}}</span>
</template>
</el-table-column>
<el-table-column prop="unit" label="单位"></el-table-column>
<el-table-column
prop="requiredQuantity"
label="计划采购数量"
v-if="sizeForm.option == 1"
>
<template slot-scope="scope">
{{ scope.row.requiredQuantity || 0 }}
</template>
</el-table-column>
<el-table-column
prop="inboundQuantity"
label="已入库数量"
v-if="sizeForm.option == 1"
>
<template slot-scope="scope">
{{ scope.row.inboundQuantity || 0 }}
</template>
</el-table-column>
<el-table-column prop="theInboundQuantity" label="本次入库数量">
<template slot-scope="scope">
<el-input-number
size="mini"
v-model="scope.row.theInboundQuantity"
:min="0"
style="width: 100%"
@change="syncInboundQuantity(scope.row)"
v-if="inDialogType != 'details'"
></el-input-number>
<span v-else>{{ scope.row.theInboundQuantity || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="unitPrice" label="单价">
<template slot-scope="scope">
<el-input-number
size="mini"
v-model="scope.row.unitPrice"
:min="0"
style="width: 100%"
@change="syncUnitPrice(scope.row)"
v-if="inDialogType != 'details' && scope.row.type !== 'YH'"
></el-input-number>
<span v-else-if="scope.row.type === 'YH'">-</span>
<span v-else>{{ scope.row.unitPrice || 0 }}</span>
</template>
</el-table-column>
</el-table>
<!-- 入库账目表格 -->
<div class="form-title" v-if="inDialogType !== 'details'">
入库账目表格:
</div>
<el-table
:data="statisticsList"
border
style="width: 100%"
v-if="inDialogType !== 'details'"
>
<el-table-column prop="date" label="当前库存">
<el-table-column
prop="inboundDetailCode"
label="入库明细单号"
v-if="inDialogType == 'details'"
>
</el-table-column>
<el-table-column prop="materialCode" label="物资编码">
</el-table-column>
<el-table-column prop="materialName" label="物资名称">
</el-table-column>
<el-table-column prop="model" label="规格"> </el-table-column>
<el-table-column prop="unit" label="单位"> </el-table-column>
<el-table-column prop="type" label="类别">
<template slot-scope="scope">
{{
scope.row.type === "NY"
? "耐用品"
: scope.row.type === "YH"
? "易耗品"
: ""
}}
</template>
</el-table-column>
<el-table-column prop="num" label="数量">
<template slot-scope="scope">
{{ scope.row.num || 0 }}
</template>
</el-table-column>
<el-table-column prop="unitPrice" label="单价">
<template slot-scope="scope">
<span v-if="scope.row.type === 'YH'">-</span>
<span v-else>{{ scope.row.unitPrice || 0 }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="date" label="入库信息">
<el-table-column prop="theInboundQuantity" label="数量">
</el-table-column>
<el-table-column prop="unitPrice" label="单价">
<template slot-scope="scope">
<span v-if="scope.row.type === 'YH'">-</span>
<span v-else>{{ scope.row.unitPrice || 0 }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="date" label="入库后库存">
<el-table-column label="数量">
<template slot-scope="scope">
{{ scope.row.totalQuantity }}
</template>
</el-table-column>
<el-table-column prop="unitPrice" label="单价">
<template slot-scope="scope">
<span v-if="scope.row.type === 'YH'">-</span>
<span v-else>{{ scope.row.unitPrice || 0 }}</span> </template
>s
</el-table-column>
</el-table-column>
<el-table-column prop="date" label="入库信息">
<el-table-column label="入库人">
<template slot-scope="scope">
{{
scope.row.userInfoVO
? scope.row.userInfoVO.name
: sizeForm.userInfoVO.name
}}
</template>
</el-table-column>
<el-table-column prop="inDate" label="入库时间" width="150">
<template slot-scope="scope">
{{ inDate }}
</template>
</el-table-column>
</el-table-column>
</el-table>
</el-form>
</div>
<span slot="footer" class="dialog-footer" v-if="!allDisabled">
<el-button @click="handleCloseDetail()">取 消</el-button>
<el-button type="primary" @click="submit(1)" :loading="isSubmitting">暂存</el-button>
<el-button type="primary" @click="submit(2)" :loading="isSubmitting">提交</el-button>
</span>
</el-dialog>
<!-- 批量出库 选择 -->
<el-dialog
:close-on-click-modal="false"
title="选择数据来源"
:visible.sync="inBatchDialogVisible"
:append-to-body="true"
width="40%"
@close="handleBatchClose"
@open="getBatchOptions"
>
<el-select
v-model="batchType"
placeholder="请选择数据来源"
style="width: 100%"
:clearable="true"
>
<el-option
v-for="item in batchOptions"
:key="item.ids"
:label="item.quarterName"
:value="item.ids"
>
</el-option>
</el-select>
<span slot="footer" class="dialog-footer">
<el-button @click="handleBatchClose()">取 消</el-button>
<el-button type="primary" @click="batchSubmit()"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {
getAllQuarter,
getPurchasesByIds,
getMaterialList,
getDetailList,
submitData,
editList,
getStatistics,
} from "@/api/firstOrder/inbound";
import { mapGetters } from "vuex";
export default {
props: {
repairVisible: {
type: Boolean,
default: false,
},
inDialogTiltle: {
type: String,
default: "",
},
inDialogType: {
type: String,
default: "",
},
type: {
type: String,
default: "",
},
id: {
type: Number,
default: 0,
},
},
data() {
return {
isSubmitting:false,
inDialogVisible: false,
sizeForm: {
orderNo: "", //入库单号
reason: "", //事由
inDate: "", //入库日期
inAccountsTableData: [], //总计
inTableData: [], //批量选择的数据
singleData: [], //单条选择
option: 2, //入库类型
options: "",
materialType: "1", //物资类型
source: "cg", //来源
status: "", //状态
quarterName: "",
purchaseEndInfo: "", //采购单信息
userInfoVO: {},
ldOnePutStorageDetailVOList: [], //入库明细
},
inTableData: [],
inBatchDialogVisible: false, //选择采购单的数据
batchType: "", //批量选择类型
materialsType: "",
allDisabled: false,
statisticsList: [], //统计明细数据
};
},
computed: {
...mapGetters(["userInfo"]),
inDate() {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
const day = String(now.getDate()).padStart(2, "0");
return `${year}${month}${day}`;
},
},
mounted() {
this.inDialogVisible = this.repairVisible;
if (this.inDialogType == "add") {
this.addInit();
} else {
this.inInit();
}
if (this.inDialogType == "details") {
this.allDisabled = true;
}
this.getBatchOptions();
this.getMaterialList();
this.sizeForm.userInfoVO = this.userInfo;
},
methods: {
// 批量 更改明细表数据
getStatistics() {
getStatistics(this.sizeForm.inTableData).then((res) => {
this.statisticsList = res.data.result;
this.statisticsList = this.statisticsList.map((stat) => {
const detail = this.sizeForm.inTableData.find(
(item) =>
item.materialCode === stat.materialCode && item.type === stat.type
);
return {
...stat,
theInboundQuantity: detail.theInboundQuantity, //本次入库数量
unitPrice: detail.unitPrice,
totalQuantity: stat.num + detail.theInboundQuantity,
};
});
});
},
// 单项 更改明细表数据
getStatisticsSingle() {
getStatistics(this.sizeForm.singleData).then((res) => {
this.statisticsList = res.data.result;
this.statisticsList = this.statisticsList.map((stat) => {
const detail = this.sizeForm.singleData.find(
(item) =>
item.materialId === stat.materialId && item.type === stat.type
);
return {
...stat,
theInboundQuantity: detail.theInboundQuantity, //本次入库数量
unitPrice: detail.unitPrice,
totalQuantity: stat.num + detail.theInboundQuantity,
};
});
});
},
//本次入库数量
syncInboundQuantity(row) {
// row.theInboundQuantity = Number(row.theInboundQuantity);
if (this.sizeForm.option == 1) {
this.getStatistics();
} else {
this.getStatisticsSingle();
}
},
//单价
syncUnitPrice(row) {
row.unitPrice = Number(row.unitPrice);
if (this.sizeForm.option == 1) {
this.getStatistics();
} else {
this.getStatisticsSingle();
}
},
//批量选择采购单数据来源
async getBatchOptions() {
this.loading = true;
try {
const res = await getAllQuarter();
this.batchOptions = res.data.result;
} catch (error) {
this.$message.error("获取数据来源失败,请重试");
} finally {
this.loading = false;
}
},
//获取单条选择的物资名称列表
async getMaterialList() {
this.loading = true;
try {
const res = await getMaterialList();
this.materials = res.data.result;
} catch (error) {
this.$message.error("获取数据来源失败,请重试");
} finally {
this.loading = false;
}
},
// 查看详情
async inInit() {
if (this.inDialogType == "details" || this.inDialogType == "edit") {
try {
const res = await editList(this.id);
const { ldOnePutStorage, ldOnePutStorageDetailList = [] } =
res.data.result || {};
if (!ldOnePutStorage) {
this.$message.error("回显数据异常");
return;
}
const handledDetailList = ldOnePutStorageDetailList.map((item) => ({
...item,
theInboundQuantity: item.inboundQuantity || 0,
}));
this.sizeForm = {
...this.sizeForm,
...ldOnePutStorage,
inDate: ldOnePutStorage.inDate
? new Date(ldOnePutStorage.inDate)
: "",
option: Number(ldOnePutStorage.options) || 1,
quarterName: ldOnePutStorage.purchaseEndInfo,
};
if (this.sizeForm.option === 1) {
this.sizeForm.inTableData = handledDetailList;
} else {
this.sizeForm.singleData = handledDetailList;
}
} catch (error) {
this.$message.error("获取详情数据失败");
}
}
},
addInit() {
this.sizeForm.inDate = new Date(); //入库时间
this.sizeForm.inTableData.theInboundQuantity = 0;
},
//取消操作
handleCloseDetail() {
this.inDialogVisible = false;
this.$emit("handleCloseDetail");
},
async inTableAdd() {
if (this.sizeForm.option == 1) {
this.sizeForm.inTableData.push({
unit: "",
model: "",
name: "",
status: "", //
materialId: "",
materialName: "",
theInboundQuantity: 0,
unitPrice: 0,
});
} else {
if (!Array.isArray(this.sizeForm.singleData)) {
this.sizeForm.singleData = [];
}
const newRow = {
unit: "",
model: "",
name: "",
status: "",
materialId: "",
materialName: "",
theInboundQuantity: 0,
unitPrice: 0,
};
this.sizeForm.singleData.push(newRow);
}
},
// 采购单选择确定
async batchSubmit() {
if (!this.batchType) {
this.$message.warning("请选择数据来源");
return;
}
const selectedOption = this.batchOptions.find(
(option) => option.ids === this.batchType
);
if (!selectedOption) {
this.$message.error("未找到对应的采购单信息");
return;
}
this.sizeForm.quarterName = selectedOption.quarterName;
this.sizeForm.purchaseEndInfo = selectedOption;
this.loading = true;
const res = await getPurchasesByIds(this.batchType);
if (res.data.success) {
this.sizeForm.inTableData = res.data.result;
this.sizeForm.inTableData.forEach((item) => {
// item.theInboundQuantity = 0;
this.$set(item, "theInboundQuantity", 0);
if (item.type == "YH") {
item.unitPrice = 0;
}
});
this.getStatistics();
this.$message.success("数据获取成功");
this.inBatchDialogVisible = false;
} else {
this.$message.error(res.data.message || "获取数据失败");
}
this.loading = false;
},
// 采购单选择弹框关闭
handleBatchClose() {
this.inBatchDialogVisible = false;
},
// 处理物资选择变化
async handleMaterialChange(row) {
if (!row.materialId) {
this.$message.warning("请选择物资名称");
return;
}
const res = await getDetailList({ id: row.materialId });
if (res.data.success) {
if (!Array.isArray(this.sizeForm.singleData)) {
this.sizeForm.singleData = [];
}
const materialData = res.data.result;
const index = this.sizeForm.singleData.findIndex(
(item) => item === row
);
if (index !== -1) {
this.$set(this.sizeForm.singleData, index, {
...row,
...materialData,
});
} else {
this.sizeForm.singleData.push({ ...row, ...materialData });
}
} else {
this.$message.error(res.data.message || "获取物资信息失败");
}
},
// 提交
async submit(index) {
if (!this.sizeForm.inDate) {
this.$message.error("入库时间不能为空");
return;
}
if (!this.sizeForm.reason) {
this.$message.error("事由不能为空");
return;
}
if (!this.sizeForm.materialType) {
this.$message.error("请选择物资类型");
return;
}
if (!this.sizeForm.source) {
this.$message.error("请选择来源");
return;
}
if (this.sizeForm.option === 1) {
//批量选择
if (!this.sizeForm.quarterName) {
this.$message.error("请选择采购单名称");
return;
}
if (
!this.sizeForm.inTableData ||
this.sizeForm.inTableData.length === 0
) {
this.$message.error("请添加批量选择数据");
return;
}
// 验证表格中的必填项
for (const row of this.sizeForm.inTableData) {
if (!row.materialId) {
this.$message.error("物资ID不能为空");
return;
}
if (!row.materialName) {
this.$message.error("物资名称不能为空");
return;
}
if (row.type === "NY") {
if (row.unitPrice === undefined || row.unitPrice <= 0) {
this.$message.error("单价不能为空");
return;
}
}
if (row.theInboundQuantity < 0) {
this.$message.error("本次入库数量不能为空");
return;
}
if (!row.type) {
this.$message.error("请选择类别");
return;
}
if (
row.theInboundQuantity + row.yetInboundQuantity >
row.requiredQuantity &&
!row.remark
) {
this.$message.warning(
row.materialName +
"本次入库数量不能大于采购单计划数量,请填写备注原因"
);
return;
}
}
}
// 单项选择验证
else if (this.sizeForm.option === 2) {
if (
!this.sizeForm.singleData ||
this.sizeForm.singleData.length === 0
) {
this.$message.error("请添加单项选择数据");
return;
}
// 验证表格中的必填项
for (const row of this.sizeForm.singleData) {
if (!row.materialId) {
this.$message.error("请选择物资名称");
return;
}
if (!row.materialName) {
this.$message.error("物资名称不能为空");
return;
}
if (row.type === "NY") {
if (row.unitPrice === undefined || row.unitPrice <= 0) {
this.$message.error("单价不能为空");
return;
}
}
if (!row.type) {
this.$message.error("请选择类别");
return;
}
}
}
// status == 1 暂存 ,2提交
this.isSubmitting = true
this.sizeForm.status = index;
if (this.sizeForm.option == 1) {
// this.sizeForm.singleData = [];
this.sizeForm.ldOnePutStorageDetailVOList = this.sizeForm.inTableData;
this.sizeForm.options = this.sizeForm.option;
this.sizeForm.purchaseEndInfo = this.sizeForm.quarterName;
// this.sizeForm.option = "";
} else if (this.sizeForm.option == 2) {
this.sizeForm.inTableData = [];
this.sizeForm.ldOnePutStorageDetailVOList = this.sizeForm.singleData;
this.sizeForm.options = this.sizeForm.option;
// this.sizeForm.option = "";
}
try {
const res = await submitData(this.sizeForm);
if (res.data.success) {
this.$message({
type: "success",
message: "提交成功",
});
// 提交成功后通知父组件更新页面
this.$emit("submitSuccess");
this.handleCloseDetail();
this.isSubmitting = false
} else {
this.$message.error(res.data.message);
this.isSubmitting = false
}
} catch (error) {
this.isSubmitting = false
this.$message.error(error.message);
}
},
// 选项选择,批量选择1 单条选择2
radioChange() {
this.batchType = "";
this.sizeForm.inTableData = [];
this.sizeForm.singleData = [];
if (this.sizeForm.option == 1) {
this.inBatchDialogVisible = true;
}
},
// type类别选择变更
handleTypeChange(row) {
if (row.type === "YH") {
// row.unitPrice = null;
if (Number(row.unitPrice) > 600) {
this.$confirm("单价大于600元,确定要选择为易耗品吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
return;
})
.catch(() => {
row.type = "NY";
this.$message({
type: "info",
message: "请重新选择类型",
});
});
}
}
if (this.sizeForm.option == 1) {
this.getStatistics();
} else {
this.getStatisticsSingle();
}
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-table td,
::v-deep .el-table th {
text-align: center !important;
}
.form-title {
margin: 20px 0;
}
::v-deep.el-dialog__footer {
position: fixed !important;
bottom: 0 !important;
right: 0 !important;
}
::v-deep.dialog-content {
max-height: calc(100vh - 200px);
overflow-y: auto;
padding-right: 10px;
}
::v-deep.el-table th.el-table__cell {
background: #f5f7fa;
font-weight: 500;
}
</style>