473 lines
16 KiB
Vue
473 lines
16 KiB
Vue
<template>
|
||
<div class="app-container bg-fff u-m-20">
|
||
<div class="head-container">
|
||
<el-form ref="queryForm" :model="queryForm" :rules="queryRules" label-position="left" label-width="100px">
|
||
<el-row>
|
||
<el-form-item label="类型">
|
||
<el-radio-group :model-value="type" @change="tabChange">
|
||
<el-radio v-if="type == 'reportinglosses'" value="reportinglosses">报损</el-radio>
|
||
<div v-else>
|
||
<el-radio value="in">入库</el-radio>
|
||
<el-radio value="out">出库</el-radio>
|
||
</div>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-row>
|
||
<div v-if="type != 'reportinglosses'">
|
||
<el-row>
|
||
<el-col v-if="type == 'in'" :span="8">
|
||
<el-form-item label="供应商">
|
||
<el-select v-model="queryForm.vendorId" placeholder="请选择供应商" clearable style="width: 220px"
|
||
@change="changeTypeEnum">
|
||
<el-option v-for="item in purveyorList" :key="item.id" :label="item.name" :value="item.id" />
|
||
</el-select>
|
||
{{ queryForm.waitAmount }}
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="出入库时间" prop="inOutDate">
|
||
<el-date-picker v-model="queryForm.inOutDate" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
|
||
placeholder="选择日期" style="width: 220px" disabled="false" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="应付金额">
|
||
<el-input v-model="queryForm.amountPayable" placeholder="请输入应收金额" style="width: 220px" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="实付金额">
|
||
<el-input v-model="queryForm.actualPaymentAmount" placeholder="请输入实收金额" style="width: 220px" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="付款时间">
|
||
<el-date-picker v-model="queryForm.paymentDate" type="date" format="YYYY-MM-DD"
|
||
value-format="YYYY-MM-DD" placeholder="选择日期" style="width: 220px" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<!-- <el-col :span="8">
|
||
<el-form-item label="批号">
|
||
<el-input v-model="queryForm.batchNo" placeholder="请输入批号" style="width: 220px" />
|
||
</el-form-item>
|
||
</el-col> -->
|
||
</el-row>
|
||
<!-- <el-row>
|
||
<el-col :span="8">
|
||
<el-form-item label="备注">
|
||
<el-input v-model="queryForm.remark" placeholder="请输入备注" style="width: 220px" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row> -->
|
||
</div>
|
||
<el-form-item label="选择耗材">
|
||
<div />
|
||
<el-button type="primary" @click="showHaocai">选择耗材</el-button>
|
||
|
||
<el-autocomplete v-model="autocompletename" :fetch-suggestions="querySearchAsync" value-key="conName"
|
||
placeholder="耗材搜索" style="width: 200px; margin-left: 20px" @select="handleSelect" />
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div style="font-weight: bold; font-size: 16px; color: #666">
|
||
共{{ tableData.list.length }}种耗材,金额合计
|
||
<span style="color: red">¥{{ amountPayable }}</span>
|
||
</div>
|
||
<div class="head-container">
|
||
<el-table :data="tableData.list">
|
||
<el-table-column label="耗材名称" prop="conName">
|
||
<template v-slot="scope">
|
||
{{ scope.row.conName }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="所属分类">
|
||
<template v-slot="scope">
|
||
{{ scope.row.consGroupName }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column>
|
||
<template v-slot="scope">
|
||
<el-input-number v-model="scope.row.price" :min="0" controls-position="right" />
|
||
<div class="tips" style="font-size: 16px">
|
||
原价¥
|
||
|
||
{{ returnPrice(scope.row, scope.row.originPrice) }}
|
||
/
|
||
{{ scope.row.unit }}
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="单位">
|
||
<template v-slot="scope">
|
||
<el-select v-model="scope.row.unit" :placeholder="scope.row.unit" @change="changeUnit(scope.row)">
|
||
<el-option :label="scope.row.conUnit" :value="scope.row.conUnit" />
|
||
<el-option v-if="scope.row.conUnitTwo" :label="scope.row.conUnitTwo" :value="scope.row.conUnitTwo" />
|
||
</el-select>
|
||
<div class="tips"> </div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="数量">
|
||
<template v-slot="scope">
|
||
<el-input-number v-model="scope.row.stockNumber" :min="0" :step="1" step-strictly
|
||
controls-position="right" />
|
||
<div class="tips" style="font-size: 16px">
|
||
{{ type == "in" ? "入库" : "出库" }}前:
|
||
{{ returnStockNumber(scope.row, scope.row.number) }}
|
||
|
||
{{ scope.row.unit }}
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- <el-table-column v-if="type == 'reportinglosses'" label="报损数量">
|
||
<template v-slot="scope">
|
||
{{ scope.row.number }}
|
||
<div class="tips" style="font-size: 16px">
|
||
入库前:
|
||
{{ returnStockNumber(scope.row, scope.row.number) }}
|
||
|
||
{{ scope.row.unit }}
|
||
</div>
|
||
</template>
|
||
</el-table-column> -->
|
||
<el-table-column v-if="type == 'reportinglosses'" label="上传图片">
|
||
<template v-slot="scope">
|
||
<MultiImageUpload v-model="scope.row.imgUrls" />
|
||
</template>
|
||
</el-table-column>
|
||
<!-- <el-table-column label="备注">
|
||
<template v-slot="scope">
|
||
<el-input v-model="textarea" stype="textarea" placeholder="" />
|
||
</template>
|
||
</el-table-column> -->
|
||
<el-table-column label="操作" width="80">
|
||
<template v-slot="scope">
|
||
<el-button link @click="tableData.list.splice(scope.$index, 1)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
<div>
|
||
<el-button type="primary" :loading="queryFormLoading" @click="submitHandle">
|
||
保存并返回
|
||
</el-button>
|
||
</div>
|
||
<!-- 选择耗材 -->
|
||
<ConsumableList ref="ConsumableList" @success="selectConsumable" />
|
||
<el-dialog v-model="showResult" :show-close="false" :close-on-press-escape="false" :close-on-click-modal="false">
|
||
<el-result icon="success" title="入库提交成功" :subTitle="`共操作${tableData.list.length}件商品`">
|
||
<template #extra>
|
||
<template>
|
||
<el-button type="primary" size="medium" @click="resetHandle">创建新的入库单</el-button>
|
||
<router-link to="/invoicing/operating_record">
|
||
<el-button size="medium">历史提交</el-button>
|
||
</router-link>
|
||
</template>
|
||
</template>
|
||
</el-result>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { ElMessage, ElMessageBox } from "element-plus";
|
||
import consApi from "@/api/product/cons";
|
||
import Decimal from "decimal.js";
|
||
import vendorApi from "@/api/product/vendor";
|
||
import stockApi from "@/api/product/stock";
|
||
import dayjs from "dayjs";
|
||
import goodsList from "./components/goods-list.vue";
|
||
import MultiImageUpload from "@/components/Upload/MultiImageUpload.vue";
|
||
|
||
import ConsumableList from "./components/consumableList.vue";
|
||
import { formatDecimal } from "@/utils/tools.js";
|
||
export default {
|
||
name: "operation_in",
|
||
components: {
|
||
goodsList,
|
||
ConsumableList,
|
||
},
|
||
data() {
|
||
return {
|
||
type: "in", //in 入库 out出库
|
||
formatDecimal,
|
||
inTabValue: "consumable",
|
||
inTabs: [
|
||
{
|
||
label: "商品入库",
|
||
value: "goods",
|
||
type: "out",
|
||
},
|
||
{
|
||
label: "耗材入库",
|
||
value: "consumable",
|
||
type: "in",
|
||
},
|
||
],
|
||
shopTypesActive: 0,
|
||
resetForm: "",
|
||
queryFormLoading: false,
|
||
queryForm: {
|
||
batchNo: "",
|
||
bodyList: [],
|
||
actualPaymentAmount: 0,
|
||
paymentDate: "",
|
||
vendorId: "",
|
||
purveyorName: "",
|
||
remark: "",
|
||
inOutDate: dayjs().format("YYYY-MM-DD"),
|
||
amountPayable: 0,
|
||
type: "in",
|
||
shopId: localStorage.getItem("shopId"),
|
||
},
|
||
queryRules: {
|
||
vendorId: [
|
||
{
|
||
required: true,
|
||
message: "请选择供应商",
|
||
trigger: "change",
|
||
},
|
||
],
|
||
inOutDate: [
|
||
{
|
||
required: true,
|
||
message: " ",
|
||
trigger: "change",
|
||
},
|
||
],
|
||
},
|
||
purveyorList: [],
|
||
tableData: {
|
||
list: [],
|
||
},
|
||
showResult: false,
|
||
autocompletename: "",
|
||
restaurants: [],
|
||
timeout: null,
|
||
};
|
||
},
|
||
computed: {
|
||
amountPayable() {
|
||
if (!this.tableData.list.length) return 0;
|
||
const zong = this.tableData.list.reduce((prve, ele) => {
|
||
return (prve += ele.price * ele.stockNumber);
|
||
}, 0);
|
||
return zong.toFixed(2);
|
||
},
|
||
},
|
||
watch: {
|
||
amountPayable(newval) {
|
||
this.queryForm.amountPayable = newval;
|
||
},
|
||
},
|
||
mounted() {
|
||
this.type = this.$route.query.type || "in";
|
||
this.resetForm = { ...this.queryForm };
|
||
this.tbShopPurveyorGet();
|
||
},
|
||
methods: {
|
||
changeUnit(row) {
|
||
row.price = this.returnPrice(row, row.originPrice);
|
||
},
|
||
returnPrice(row, price = 0) {
|
||
if (!row.unit) {
|
||
return price;
|
||
}
|
||
if (row.unit == row.conUnit) {
|
||
return price;
|
||
}
|
||
if (row.conUnitTwo && row.unit == row.conUnitTwo) {
|
||
// console.log(price / row.conUnitTwoConvert);
|
||
// console.log(new Decimal(price).div(new Decimal(row.conUnitTwoConvert)));
|
||
return new Decimal(price).mul(new Decimal(row.conUnitTwoConvert));
|
||
}
|
||
return price;
|
||
},
|
||
returnStockNumber(row, number = 0) {
|
||
if (!row.unit) {
|
||
return number;
|
||
}
|
||
if (row.unit == row.conUnit) {
|
||
return number;
|
||
}
|
||
if (row.conUnitTwo && row.unit == row.conUnitTwo) {
|
||
return number / row.conUnitTwoConvert;
|
||
}
|
||
return number;
|
||
},
|
||
showHaocai() {
|
||
this.$refs.ConsumableList.show(this.tableData.list);
|
||
},
|
||
async querySearchAsync(queryString, cb) {
|
||
//快捷搜索
|
||
let res = null;
|
||
|
||
res = await consApi.getList({
|
||
page: 0,
|
||
size: 20,
|
||
conName: queryString ? queryString : "",
|
||
});
|
||
this.restaurants = res.records;
|
||
if (res.records.length == 0) {
|
||
//给个提示没有搜到
|
||
ElMessage("无此耗材");
|
||
return false;
|
||
}
|
||
var uniqueArray = this.restaurants.filter(
|
||
(item1) => !this.tableData.list.some((item2) => item2.productId == item1.id)
|
||
);
|
||
clearTimeout(this.timeout);
|
||
this.timeout = setTimeout(() => {
|
||
cb(uniqueArray);
|
||
}, 1000 * Math.random());
|
||
},
|
||
xiaoji(row) {
|
||
const price = row.price * row.stockNumber;
|
||
return price;
|
||
},
|
||
|
||
handleSelect(item) {
|
||
//选定后清空
|
||
this.autocompletename = "";
|
||
this.selectConsumable([item]);
|
||
},
|
||
|
||
// 切换入库内容
|
||
tabChange(value) {
|
||
this.shopTypesActive = value == "in" ? 0 : 1;
|
||
this.inTabValue = value;
|
||
this.type = value;
|
||
this.resetHandle();
|
||
// this.$refs.shopList.reset(); //清除选项
|
||
// this.$refs.ConsumableList.reset(); //清除选项
|
||
},
|
||
// 切换类型
|
||
changeTypeEnum(index) {
|
||
let filterd = this.purveyorList.filter((ele) => ele.id == index);
|
||
this.queryForm.waitAmount = filterd[0].waitAmount;
|
||
|
||
this.inTabs.forEach((i) => {
|
||
if (i.value == this.inTabValue) {
|
||
this.queryForm.type = i.type;
|
||
}
|
||
});
|
||
if (this.inTabValue == "consumable") {
|
||
return false;
|
||
}
|
||
//商品入库是否显示应付实付
|
||
if (this.queryForm.vendorId) {
|
||
this.shopTypesActive = 0;
|
||
} else {
|
||
this.shopTypesActive = 1;
|
||
}
|
||
},
|
||
// 提交
|
||
submitHandle() {
|
||
if (this.tableData.list.length == 0) {
|
||
ElMessage("请先选择耗材!");
|
||
return;
|
||
}
|
||
this.$refs.queryForm.validate(async (valid) => {
|
||
if (valid) {
|
||
try {
|
||
this.queryFormLoading = true;
|
||
const bodyList = this.tableData.list.map((v) => {
|
||
let inOutNumber = v.stockNumber;
|
||
if (v.unit == v.conUnit) {
|
||
inOutNumber = v.stockNumber;
|
||
}
|
||
if (v.conUnitTwo && v.unit == v.conUnitTwo) {
|
||
inOutNumber = v.stockNumber * v.conUnitTwoConvert;
|
||
}
|
||
return {
|
||
conId: v.id,
|
||
conName: v.conName,
|
||
purchasePrice: v.price,
|
||
unitName: v.conUnit,
|
||
inOutNumber: inOutNumber,
|
||
subTotal: this.xiaoji(v),
|
||
imgUrls: v.imgUrls,
|
||
number: inOutNumber,
|
||
};
|
||
});
|
||
if (this.type == "in") {
|
||
await stockApi.in({ ...this.queryForm, bodyList });
|
||
} else if (this.type == "out") {
|
||
await stockApi.out({ ...this.queryForm, bodyList });
|
||
} else if (this.type == "reportinglosses") {
|
||
await stockApi.reportDamage(bodyList);
|
||
}
|
||
this.queryFormLoading = false;
|
||
// const title = this.type == "in" ? "入库" : "出库";
|
||
ElMessage({
|
||
// message: title + "提交成功",
|
||
message: "提交成功",
|
||
type: "success",
|
||
});
|
||
this.$router.push("/inventory/consumables");
|
||
this.showResult = true;
|
||
// this.$refs.shopList.reset()//清除选项
|
||
// this.$refs.ConsumableList.reset()//清除选项
|
||
} catch (error) {
|
||
console.log(error);
|
||
this.queryFormLoading = false;
|
||
}
|
||
}
|
||
});
|
||
},
|
||
// 选择耗材
|
||
selectConsumable(res) {
|
||
console.log(res);
|
||
let arr = res.map((item) => {
|
||
item.number = item.stockNumber;
|
||
item.stockNumber = 0;
|
||
item.costPrice = item.price;
|
||
item.conInfoId = item.id;
|
||
item.unit = item.defaultUnit || item.conUnit;
|
||
item.originPrice = item.price;
|
||
item.price = this.returnPrice(item, item.price);
|
||
item.imgUrls = item.imgUrls ? item.imgUrls : [];
|
||
return item;
|
||
});
|
||
this.tableData.list = [...this.tableData.list, ...arr];
|
||
},
|
||
|
||
// 初始化
|
||
resetHandle() {
|
||
this.showResult = false;
|
||
this.queryForm = { ...this.resetForm };
|
||
console.log(this.inTabs, this.inTabValue);
|
||
this.queryForm.type = this.inTabs.find((item) => item.type == this.inTabValue).type;
|
||
this.tableData.list = [];
|
||
this.$refs.queryForm.resetFields();
|
||
},
|
||
|
||
// 获取供应商列表
|
||
async tbShopPurveyorGet() {
|
||
try {
|
||
const res = await vendorApi.getList({});
|
||
this.purveyorList = res.records;
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.name_wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.name {
|
||
margin-right: 10px;
|
||
}
|
||
}
|
||
|
||
.app-container {}
|
||
</style>
|