Files
cashier-web/src/views/inventory/operation_in/index.vue
2025-03-07 18:53:31 +08:00

687 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
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.
<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="80px"
>
<el-row>
<el-col :span="8">
<el-form-item label="供应商">
<el-select
v-model="queryForm.purveyorId"
placeholder="请选择供应商"
clearable
style="width: 220px"
@change="changeTypeEnum"
>
<el-option
:label="item.name"
:value="item.id"
v-for="item in purveyorList"
:key="item.id"
></el-option>
</el-select>
{{ queryForm.waitAmount }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="入库时间" prop="time">
<el-date-picker
v-model="queryForm.time"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
style="width: 220px"
></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
<el-col :span="8">
<el-form-item label="应付金额">
<el-input
v-model="queryForm.totalAmount"
placeholder="请输入应收金额"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="实付金额">
<el-input
v-model="queryForm.paidAmount"
placeholder="请输入实收金额"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
<el-col :span="8">
<el-form-item label="付款时间">
<el-date-picker
v-model="queryForm.paidAt"
type="date"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="选择日期"
style="width: 220px"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="批号">
<el-input
v-model="queryForm.batchNumber"
placeholder="请输入批号"
style="width: 220px"
></el-input>
</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-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="showHaocai" v-if="inTabValue == 'consumable'">
选择耗材
</el-button>
<el-button type="primary" @click="$refs.shopList.show(tableData.list)" v-else>
选择商品
</el-button>
</el-form-item>
<el-autocomplete
v-model="autocompletename"
:fetch-suggestions="querySearchAsync"
:value-key="inTabValue == 'goods' ? 'name' : 'conName'"
:placeholder="inTabValue == 'goods' ? '商品搜索' : '耗材搜索'"
@select="handleSelect"
style="width: 500px"
></el-autocomplete>
</el-form>
</div>
<div class="head-container">
<el-button type="primary" plain v-if="inTabValue == 'consumable'">
{{ tableData.list.length }}种耗材金额合计
<span style="color: red">{{ queryForm.totalAmount }}</span>
</el-button>
<el-button type="primary" plain v-else>
{{ tableData.list.length }}种商品金额合计
<span style="color: red">{{ queryForm.totalAmount }}</span>
</el-button>
</div>
<div class="head-container">
<el-table :data="tableData.list" v-if="inTabValue == 'consumable'">
<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">
<el-input-number
v-model="scope.row.price"
:min="0"
controls-position="right"
@change="consCountTotal($event, scope.row, 'price')"
></el-input-number>
<div class="tips" style="font-size: 16px">
原价
<!-- {{ scope.row.costPrice }}/{{ scope.row.conUnit }} -->
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit == scope.row.conUnitTwo
? (scope.row.costPrice * scope.row.conUnitTwoConvert).toFixed(2)
: scope.row.costPrice
: scope.row.costPrice
: scope.row.unit == scope.row.conUnitTwo
? (scope.row.costPrice * scope.row.conUnitTwoConvert).toFixed(2)
: scope.row.costPrice
}}
/
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit
: scope.row.conUnit
: scope.row.unit
}}
</div>
</template>
</el-table-column>
<el-table-column label="单位">
<template v-slot="scope">
<el-select
@change="consCountTotal($event, scope.row, 'unit')"
v-model="scope.row.unit"
:placeholder="scope.row.defaultUnit ? scope.row.defaultUnit : scope.row.conUnit"
>
<el-option :label="scope.row.conUnit" :value="scope.row.conUnit"></el-option>
<el-option
:label="scope.row.conUnitTwo"
:value="scope.row.conUnitTwo"
v-if="scope.row.conUnitTwo"
></el-option>
</el-select>
<div class="tips">&nbsp;</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"
@change="consCountTotal($event, scope.row, 'stockNumber')"
></el-input-number>
<div class="tips" style="font-size: 16px">入库前</div>
</template>
</el-table-column>
<el-table-column label="小计">
<template v-slot="scope">
<!-- <el-input-number v-model="scope.row.totalAmount" :min="0" scope.row.price , scope.row.stockNumber
controls-position="right"></el-input-number> -->
<el-input :value="formatDecimal(testform(scope.row))" readonly style="width: 100px" />
</template>
</el-table-column>
<!-- <el-table-column label="变动后剩余库存">
<template v-slot="scope">
{{ scope.row.stockNumber + scope.row.number }}{{ scope.row.conUnit }}
</template>
</el-table-column> -->
<el-table-column label="操作" width="80">
<template v-slot="scope">
<el-button link @click="tableData.list.splice(scope.$index, 1), spliceclick()">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-table :data="tableData.list" v-else>
<el-table-column type="index" width="50"></el-table-column>
<el-table-column label="商品名称" prop="name">
<template v-slot="scope">
<div class="name_wrap">
<span class="name">{{ scope.row.name }}</span>
<span v-if="scope.row.specSnap">({{ scope.row.specSnap }})</span>
<!-- <el-tag type="info" v-if="scope.row.specSnap" size="mini">{{ scope.row.specSnap }}</el-tag> -->
</div>
</template>
</el-table-column>
<el-table-column label="进价">
<template v-slot="scope">
<el-input-number
v-model="scope.row.costPrice"
:min="0"
controls-position="right"
@change="modifyPrice($event, scope.row, 'costPrice')"
></el-input-number>
<div class="tips">成本价{{ scope.row.costPrice }}/{{ scope.row.unitName }}</div>
</template>
</el-table-column>
<el-table-column label="数量">
<template v-slot="scope">
<el-input-number
v-model="scope.row.number"
:min="0"
:step="1"
step-strictly
controls-position="right"
@change="modifyPrice($event, scope.row, 'number', 'totalAmount')"
></el-input-number>
<div class="tips" style="font-size: 16px">
入库前
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit == scope.row.conUnitTwo
? scope.row.number / scope.row.conUnitTwoConvert
: scope.row.number
: scope.row.number
: scope.row.unit == scope.row.conUnitTwo
? scope.row.number / scope.row.conUnitTwoConvert
: scope.row.number
}}
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit
: scope.row.conUnit
: scope.row.unit
}}
</div>
</template>
</el-table-column>
<el-table-column label="小计">
<template v-slot="scope">
<!-- <el-input-number v-model="scope.row.totalAmount" :min="0"
controls-position="right"></el-input-number> -->
<el-input
:value="scope.row.costPrice * scope.row.number"
readonly
style="width: 100px"
/>
</template>
</el-table-column>
<el-table-column label="变动后剩余库存">
<template v-slot="scope">
{{ scope.row.stockNumber + scope.row.number }}{{ scope.row.unitName }}
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template v-slot="scope">
<el-button type="text" @click="tableData.list.splice(scope.$index, 1), spliceclick()">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div>
<el-button type="primary" @click="submitHandle" :loading="queryFormLoading">确定</el-button>
</div>
<!-- 选择商品 -->
<shopList ref="shopList" @success="selectShop" />
<!-- 选择耗材 -->
<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 vendorApi from "@/api/product/vendor";
import stockApi from "@/api/product/stock";
import dayjs from "dayjs";
import shopList from "./components/shopList.vue";
import ConsumableList from "./components/consumableList.vue";
import { formatDecimal } from "@/utils/tools.js";
export default {
name: "operation_in",
components: {
shopList,
ConsumableList,
},
data() {
return {
formatDecimal,
inTabValue: "consumable",
inTabs: [
{
label: "商品入库",
value: "goods",
type: "purveyor",
},
{
label: "耗材入库",
value: "consumable",
type: "in",
},
],
shopTypesActive: 0,
shopTypes: [
{
label: "供应商入库",
value: "purveyor",
},
{
label: "其他入库",
value: "purchase",
},
],
shopTypes2: [
{
label: "供应商入库",
value: "purveyor",
},
],
resetForm: "",
queryFormLoading: false,
queryForm: {
batchNumber: "",
list: [],
paidAmount: 0,
paidAt: "",
purveyorId: "",
purveyorName: "",
remark: "",
time: dayjs().format("YYYY-MM-DD"),
totalAmount: 0,
type: "in",
shopId: localStorage.getItem("shopId"),
},
queryRules: {
purveyorId: [
{
required: true,
message: "请选择供应商",
trigger: "change",
},
],
time: [
{
required: true,
message: " ",
trigger: "change",
},
],
},
purveyorList: [],
tableData: {
list: [],
},
showResult: false,
autocompletename: "",
restaurants: [],
timeout: null,
};
},
mounted() {
this.resetForm = { ...this.queryForm };
this.tbShopPurveyorGet();
},
methods: {
showHaocai() {
this.$refs.ConsumableList.show(this.tableData.list);
},
async querySearchAsync(queryString, cb) {
//快捷搜索
let res = null;
if (this.inTabValue == "goods") {
res = await tbProductlist({
page: 0,
size: 20,
name: queryString ? queryString : "",
shopId: localStorage.getItem("shopId"),
sort: "id",
});
} else {
res = await tbConsInfoGet({
page: 0,
size: 20,
shopId: localStorage.getItem("shopId"),
conName: queryString ? queryString : "",
});
}
this.restaurants = res.content;
if (res.content.length == 0) {
//给个提示没有搜到
this.$message("无此商品");
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());
},
testform(d) {
let p = 1;
if (d.unit && d.unit == d.conUnitTwo) {
p = d.conUnitTwoConvert;
}
return d.price * d.stockNumber * p;
},
handleSelect(item) {
//选定后清空
this.autocompletename = "";
if (this.inTabValue == "goods") {
this.selectShop([item]);
} else {
this.selectConsumable([item]);
}
},
//删除计算
spliceclick() {
var zong = 0;
if (this.inTabValue == "goods") {
this.tableData.list.forEach((ele) => {
zong += ele.costPrice * ele.number;
});
} else {
this.tableData.list.forEach((ele) => {
let p = 1;
if (ele.unit && ele.conUnitTwo == ele.unit) {
p = ele.conUnitTwoConvert;
}
zong += ele.price * ele.stockNumber * p;
});
}
this.queryForm.totalAmount = formatDecimal(zong);
},
// 选择商品
selectShop(res) {
let arr = [];
res.forEach((item) => {
item.skuList.forEach((i) => {
arr.push({
name: item.name,
unitName: item.unitName,
productId: item.id,
number: 0,
totalAmount: "",
...i,
});
});
});
this.tableData.list = [...this.tableData.list, ...arr];
},
// 切换入库内容
tabChange(value, type) {
this.shopTypesActive = type == "in" ? 0 : 1;
this.inTabValue = 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.purveyorId) {
this.shopTypesActive = 0;
} else {
this.shopTypesActive = 1;
}
},
// 计算耗材总价
consCountTotal(cvalue, row, key1, key2 = undefined) {
if (cvalue == undefined) {
setTimeout(() => {
row[key1] = 0;
let zong = 0;
this.tableData.list.forEach((ele) => {
zong += ele.price * ele.stockNumber;
});
this.queryForm.totalAmount = formatDecimal(zong);
}, 10);
} else {
row[key1] = cvalue;
let zong = 0;
this.tableData.list.forEach((ele) => {
let p = 1;
if (ele.unit && ele.conUnitTwo == ele.unit) {
p = ele.conUnitTwoConvert;
}
zong += ele.price * ele.stockNumber * p;
});
this.queryForm.totalAmount = formatDecimal(zong);
}
},
// 计算商品总价
modifyPrice(cvalue, row, key1, key2 = undefined) {
if (cvalue == undefined) {
setTimeout(() => {
row[key1] = 0;
row[key2] = 0;
let zong = 0;
this.tableData.list.forEach((ele) => {
zong += ele.costPrice * ele.number;
});
this.queryForm.totalAmount = formatDecimal(zong);
}, 10);
} else {
row[key1] = cvalue;
row[key2] = cvalue;
let zong = 0;
this.tableData.list.forEach((ele) => {
zong += ele.costPrice * ele.number;
});
this.queryForm.totalAmount = formatDecimal(zong);
}
},
// 提交
submitHandle() {
if (this.tableData.list.length == 0) {
switch (this.inTabValue) {
case "goods":
this.$message("请先选择商品!");
break;
case "consumable":
this.$message("请先选择耗材!");
break;
default:
break;
}
return false;
}
this.$refs.queryForm.validate(async (valid) => {
if (valid) {
try {
this.queryFormLoading = true;
switch (this.inTabValue) {
case "goods":
this.queryForm.list = this.tableData.list;
await tbProductStockOperateOutAndOn(this.queryForm);
break;
case "consumable":
this.queryForm.accountsPayable = this.queryForm.totalAmount;
this.queryForm.actualPayment = this.queryForm.paidAmount;
this.queryForm.paymentTime = this.queryForm.paidAt;
this.queryForm.supplierId = this.queryForm.purveyorId;
this.queryForm.list = this.tableData.list;
await stockApi.in(this.queryForm);
break;
default:
break;
}
this.queryFormLoading = false;
this.$message({
message: "入库提交成功",
type: "success",
});
this.resetHandle(); //初始化
// 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 = formatDecimal(item.stockNumber - item.stockConsume, 2, true);
item.stockNumber = 0;
item.costPrice = item.price;
item.conInfoId = item.id;
return item;
});
this.tableData.list = [...this.tableData.list, ...arr];
},
// 初始化
resetHandle() {
this.showResult = false;
this.queryForm = { ...this.resetForm };
if (this.inTabValue == "goods") {
this.queryForm.type = "purveyor";
} else {
this.queryForm.type = this.inTabs.find((item) => item.value == this.inTabValue).type;
}
this.tableData.list = [];
this.$refs.queryForm.resetFields();
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>