516 lines
14 KiB
Vue
516 lines
14 KiB
Vue
<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> |