web/src/components/inventory/check/Add.vue

516 lines
14 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>
<Mask :width="1200" :height="540" :is-show="isShow" @close="exit" title="新增盘点" :show-footer="true">
<div class="body_wrapper">
<div class="top" style="width: 100%">
<el-form :model="form" :inline=true style="width: 100%" label-width="auto" class="demo-ruleForm" label-position="top">
<el-form-item label="盘点人">
<el-select
v-model="form.checkUserId"
placeholder="选择盘点人"
style="width: 240px"
>
<el-option
v-for="item in managerUserList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="备注" style="width: 50%;margin-right: 0">
<el-input v-model="form.remark"></el-input>
</el-form-item>
</el-form>
</div>
<div class="content">
<div class="add_goods">
<span>盘点药品</span>
<div class="search">
<GoodsSearch @selectCallBack="goodsSelectCallBack"></GoodsSearch>
</div>
</div>
<table class="simple-table" style="margin-top: 15px;">
<thead>
<tr>
<th>名称</th>
<th>批次</th>
<th>最小包装数量</th>
<th>库存</th>
<th>改后库存</th>
<th>变化量</th>
</tr>
</thead>
<tbody>
<template v-for="(item,index) in list">
<tr>
<td>{{ item.name }}</td>
<td>
<!--<el-checkbox-group v-model="item.childIdList" @change="addLine(item)">
<el-checkbox v-for="(subItem,subIndex) in item.selectList" :label="subItem.id" :value="subItem.id" />
</el-checkbox-group>-->
<el-select
v-model="item.childIdList"
@change="addLine(item)"
multiple
:teleported="false"
style="width: 150px;"
collapse-tags
popper-class="table-select">
<div class="select-header">
<span>批次ID</span>
<span>生产批号</span>
<span>入库时间</span>
<span>有效期</span>
<span>进价</span>
</div>
<el-option
v-for="(subItem,subIndex) in item.selectList"
:key="subItem.id"
:label="subItem.id"
:value="subItem.id">
<div class="option-row">
<span>{{ subItem.id }}</span>
<span>{{ subItem.productionBatchCode }}</span>
<span>{{ subItem.productionDate }}</span>
<span>{{ subItem.expiryDate }}</span>
<span>{{ subItem.purchaseUnitPrice }}</span>
</div>
</el-option>
</el-select>
</td>
<td>{{ item.minPackagingNumber }}</td>
<td>
{{ item.before.wholeNumber }}{{ item.packagingUnit }}
<template v-if="item.trdnFlag ==1">
{{ item.before.fragmentNumber }}{{ item.minPackagingUnit }}
</template>
</td>
<td>
<el-form v-show="item.childIdList.length===0">
<el-input v-model.number="item.after.wholeNumber" style="width: 60px" @change="setChange(item)">
<template #suffix>{{ item.packagingUnit }}</template>
</el-input>
<el-input v-model.number="item.after.fragmentNumber" style="width: 60px;margin-left: 5px"
@change="setChange(item)" v-if="item.trdnFlag ==1">
<template #suffix>{{ item.minPackagingUnit }}</template>
</el-input>
</el-form>
</td>
<td>
{{ item.change.wholeNumber }}{{ item.packagingUnit }}
<template v-if="item.trdnFlag ==1">
{{ item.change.fragmentNumber }}{{ item.minPackagingUnit }}
</template>
</td>
</tr>
<template v-for="(subItem,subIndex) in item.children">
<tr>
<td>-</td>
<td>-</td>
<td>-</td>
<td> {{ subItem.before.wholeNumber }}{{ item.packagingUnit }}
<template v-if="item.trdnFlag ==1">
{{ subItem.before.fragmentNumber }}{{ item.minPackagingUnit }}
</template>
</td>
<td>
<el-input v-model.number="subItem.after.wholeNumber" style="width: 60px" @change="setChange(subItem)">
<template #suffix>{{ item.packagingUnit }}</template>
</el-input>
<el-input v-model.number="subItem.after.fragmentNumber" style="width: 60px;margin-left: 5px"
@change="setChange(subItem)" v-if="item.trdnFlag ==1">
<template #suffix>{{ item.minPackagingUnit }}</template>
</el-input>
</td>
<td>
{{ subItem.change.wholeNumber }}{{ item.packagingUnit }}
<template v-if="item.trdnFlag ==1">
{{ item.change.fragmentNumber }}{{ item.minPackagingUnit }}
</template>
</td>
</tr>
</template>
</template>
</tbody>
</table>
</div>
</div>
<template #footer>
<div class="bottom">
<div class="btn">
<el-button @click="save" type="primary">保存</el-button>
<el-button @click="exit" type="primary">关闭</el-button>
</div>
</div>
</template>
</Mask>
</template>
<script setup lang="ts">
import {post} from "@/utils/request.ts";
import {ref} from "vue";
import GoodsSearch from "@/components/inventory/GoodsSearch.vue";
import Mask from "@/components/common/Mask.vue";
import {ElMessage} from "element-plus";
const form = ref<any>({
remark: ""
})
const state = ref([])
const goodsSelectCallBack = (item: any) => {
if (findIndexForTableList(item.goodId) != -1) {
return
}
addRow(item.goodId);
state.value = []
}
const findIndexForTableList = (goodId: any) => {
return list.value.findIndex((item: any) => item.goodsId === goodId);
}
interface Check {
id?: number,
goodsId: number,
name: string,
minPackagingUnit: string,
packagingUnit: string,
minPackagingNumber: number,
listSize: number,
trdnFlag: number,
childIdList: number[],
before: {
wholeNumber: number,
fragmentNumber: number,
},
after: {
wholeNumber: number,
fragmentNumber: number,
},
change: {
wholeNumber: number,
fragmentNumber: number,
}
children: childCheck[],
selectList: seletcType[],
}
interface seletcType {
id: number,
wholeNumber: number,
fragmentNumber: number,
productionBatchCode: string,
productionDate: string,
expiryDate: string,
purchaseUnitPrice: string
}
interface childCheck {
id?: number,
goodsId: number,
name: string,
minPackagingNumber: number,
before: {
wholeNumber: number,
fragmentNumber: number,
},
after: {
wholeNumber: number,
fragmentNumber: number,
},
change: {
wholeNumber: number,
fragmentNumber: number,
}
}
const list = ref<Check[]>([])
const emit = defineEmits(['close'])
let setChange = function (row: any) {
let totalBefore = row.before.wholeNumber * row.minPackagingNumber + row.before.fragmentNumber; // 使用原始数据
let totalAfter = row.after.wholeNumber * row.minPackagingNumber + row.after.fragmentNumber; // 使用原始数据
console.log(totalBefore, totalAfter)
let diff = totalAfter - totalBefore;
row.change.wholeNumber = Math.trunc(diff / row.minPackagingNumber);
row.change.fragmentNumber = diff % row.minPackagingNumber
}
let addLine = (row: any) => {
post("inventory/goods/getListByIds", {idList: row.childIdList}).then((list: any) => {
let children = [];
for (let i = 0; i < list.length; i++) {
let inventoryGoods = list[i];
let index = row.children.findIndex((item: any) => item.id === inventoryGoods.id);
if (index > -1) {
children.push(row.children[index]);
} else {
let childCheck: childCheck = {
name: inventoryGoods.name,
id: inventoryGoods.id,
goodsId: inventoryGoods.goodId,
minPackagingNumber: row.minPackagingNumber,
before: {
wholeNumber: inventoryGoods.wholeNumber,
fragmentNumber: inventoryGoods.fragmentNumber,
},
after: {
wholeNumber: inventoryGoods.wholeNumber,
fragmentNumber: inventoryGoods.fragmentNumber,
},
change: {
wholeNumber: 0,
fragmentNumber: 0,
}
}
children.push(childCheck);
}
}
row.children = children;
})
}
let addRow = (goodsId: number) => {
post("inventory/goods/getByGoodsId", {goodsId, isZero: true}).then((res: any) => {
let check: Check = {
goodsId: res.id,
name: res.name,
listSize: res.listSize,
childIdList: [],
minPackagingNumber: res.minPackagingNumber,
packagingUnit: res.packagingUnit,
minPackagingUnit: res.minPackagingUnit,
trdnFlag: res.trdnFlag,
before: {
wholeNumber: res.wholeNumber,
fragmentNumber: res.fragmentNumber,
},
after: {
wholeNumber: res.wholeNumber,
fragmentNumber: res.fragmentNumber,
},
change: {
wholeNumber: 0,
fragmentNumber: 0,
},
children: [],
selectList: [],
}
let inventoryGoodsList = res.inventoryGoodsList
for (let i = 0; i < inventoryGoodsList.length; i++) {
let inventoryGoods = inventoryGoodsList[i];
let childCheck: seletcType = {
id: inventoryGoods.id,
wholeNumber: inventoryGoods.wholeNumber,
fragmentNumber: inventoryGoods.fragmentNumber,
productionBatchCode: inventoryGoods.productionBatchCode,
productionDate: inventoryGoods.productionDate,
expiryDate: inventoryGoods.expiryDate,
purchaseUnitPrice: inventoryGoods.purchaseUnitPrice,
}
check.selectList.push(childCheck)
}
list.value.push(check)
})
}
let save = () => {
post("inventory/check/save", {list: list.value, remark: form.value.remark,checkUserId: form.value.checkUserId}).then((res: any) => {
ElMessage.success('保存成功')
exit()
})
}
let exit = () => {
form.value = {
remark: ""
}
list.value=[]
isShow.value = false
emit('close');
}
const isShow = ref<any>(false)
const init = () => {
isShow.value = true
getManagerUserList()
getUserInfo()
}
defineExpose({init})
const managerUserList: any = ref([])
const getManagerUserList = () => {
post("manager/user/list", {}).then((res: any) => {
managerUserList.value = res
})
}
const getUserInfo = () => {
post("manager/user/verify", null).then((res: any) => {
form.value.useUserId = res.id;
})
}
</script>
<style scoped lang="scss">
.body_wrapper {
width: 100%;
height: 100%;
display: flex;
min-height: 0;
flex-direction: column;
margin-top: 24px;
padding: 0 24px;
.top {
position: relative;
width: 100%;
}
.content {
display: block;
width: 100%;
flex: 1;
.add_goods {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 800;
font-size: 18px;
color: #333333;
font-style: normal;
.search {
width: 50%;
}
}
//min-height: 0;
table {
//border-collapse: collapse;
width: 100%;
}
th,
td {
//border: 1px solid #ccc;
padding: 8px;
text-align: left;
}
th {
//background-color: #F9F9F9;
}
/* 可选为可点击的行添加鼠标悬停效果 */
tr:hover {
//background-color: #f5f5f5;
}
}
.bottom {
height: 60px;
position: absolute;
right: 10px;
bottom: 10px;
}
}
.header {
display: flex;
.text {
font-size: 16px;
width: 200px;
color: #6a6a6a;
}
}
/* 表格容器 */
.simple-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
border: none;
color: #606266;
thead {
background-color: #f5f7fa;
th {
padding: 12px 0;
text-align: left;
font-weight: bold; /* 表头加粗 */
font-size: 14px; /* 表头字号 */
border-bottom: 1px solid #ebeef5;
}
}
tbody {
tr:hover {
background-color: #f5f7fa; /* 悬停效果 */
}
td {
padding: 12px 0;
text-align: left;
font-size: 14px; /* 单元格字号 */
border-bottom: 1px solid #ebeef5;
}
}
}
.table-select {
.el-select-dropdown__item {
padding: 0 !important;
height: auto;
}
// 表头样式
.select-header {
display: flex;
padding: 8px 16px;
background: #f5f7fa;
border-bottom: 1px solid #ebeef5;
span {
flex: 1;
min-width: 110px;
font-weight: bold;
}
}
// 选项行样式
.option-row {
display: flex;
padding: 8px 16px;
span {
flex: 1;
min-width: 110px;
}
}
}
.remark {
// 前置标签背景色
:deep(.el-input-group__prepend) {
background-color: #fffdec;
}
// 输入框主体背景色
:deep(.el-input__wrapper) {
background-color: #fffdec;
}
}
.bottom {
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
padding: 0 24px;
}
</style>