web/src/components/inventory/apply/AddApply.vue

392 lines
11 KiB
Vue

<template>
<Mask :width="1200" :height="600" :top="100" :is-show="isShow" @close="exit" title="新增领用" :show-footer="true">
<div class="add-panel">
<div class="top">
<el-form :inline=true label-position="top" :model="formData" label-width="auto">
<el-form-item label="领用人">
<el-input v-model="formData.name" disabled></el-input>
</el-form-item>
<el-form-item label="备注" style="width: 50%">
<el-input v-model="formData.remark"></el-input>
</el-form-item>
</el-form>
</div>
<div class="table_content">
<div class="add_apply">
<span>领用药品</span>
<div class="search">
<GoodsSearch @selectCallBack="goodsSelectCallBack"></GoodsSearch>
</div>
</div>
<table class="simple-table" style="margin-top: 15px;width: 100% ;height:300px ;max-height:550px">
<thead>
<tr>
<th>名称</th>
<th>批次</th>
<th>生产批号</th>
<th>有效期</th>
<th>当前库存</th>
<th>出库数量</th>
</tr>
</thead>
<tbody>
<template v-for="(item,index) in tableList">
<tr>
<td>{{ item.name }}</td>
<td>
<el-select
v-model="item.selectList"
multiple
@change="addLine(item)"
:teleported="false"
style="width: 100px;"
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.batchList"
: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></td>
<td>
</td>
<td>
{{ item.wholeNumber }}{{ item.packagingUnit }}
<template v-if="item.trdnFlag == 1">
{{ item.fragmentNumber }}{{ item.minPackagingUnit }}
</template>
</td>
<td>
{{ item.totalOutWholeNumber }}{{ item.packagingUnit }}
<template v-if="item.trdnFlag == 1">
{{ item.totalFragmentNumber }}{{ item.minPackagingUnit }}
</template>
</td>
</tr>
<template v-for="subItem in item.children">
<tr>
<td>-</td>
<td>-</td>
<td>{{ subItem.productionBatchCode }}</td>
<td>{{ subItem.expiryDate }}</td>
<td>
{{ subItem.wholeNumber }}{{ subItem.packagingUnit }}
<template v-if="item.trdnFlag == 1">
{{ subItem.fragmentNumber }}{{ subItem.minPackagingUnit }}
</template>
</td>
<td>
<el-input v-model.number="subItem.outWholeNumber" size="small" style="width: 50px"
@change="changeOutNumber(item)">
<template #suffix>
{{ item.packagingUnit }}
</template>
</el-input>
<el-input v-model.number="subItem.outFragmentNumber" size="small" style="width: 50px"
@change="changeOutNumber(item)" v-if="item.trdnFlag == 1">
<template #suffix>
{{ item.minPackagingUnit }}
</template>
</el-input>
</td>
</tr>
</template>
</template>
</tbody>
</table>
</div>
</div>
<template #footer>
<div class="bottom">
<el-button type="primary" @click="save">保存</el-button>
<el-button type="primary" @click="exit">关闭</el-button>
</div>
</template>
</Mask>
</template>
<script setup lang="ts">
import {onMounted, ref, unref} from "vue";
import GoodsSearch from "@/components/inventory/GoodsSearch.vue";
import {post} from "@/utils/request.ts";
import CloseBtn from "@/components/CloseBtn.vue";
import Mask from "@/components/common/Mask.vue";
const isShow = ref<any>(false)
const emit = defineEmits(['close'])
const exit = () => {
isShow.value = false
emit('close')
}
const formData = ref({
useUserId: null,
name: '',
username: "",
remark: ''
})
interface Inventory {
goodId: string | number;
batchList?: any[];// 添加 batchList 属性
children: childCheck[];
packagingUnit?: string;
minPackagingUnit?: string;
totalOutWholeNumber: number;
totalFragmentNumber: number;
wholeNumber?: number;
fragmentNumber?: number;
selectList?: number[]; // 添加 selectList 属性并指定类型
name?: string;
trdnFlag?: number;
}
const tableList = ref<Inventory[]>([]);
const findIndexForTableList = (goodId: any) => {
return tableList.value.findIndex((item: any) => item.goodId === goodId);
}
const goodsSelectCallBack = (inventory: any) => {
if (findIndexForTableList(inventory.goodId) != -1) {
return
}
post("inventory/goods/getByGoodsId", {goodsId: inventory.goodId,isZero:false}).then((res: any) => {
inventory.batchList = res.inventoryGoodsList
inventory.minPackagingUnit = res.minPackagingUnit
inventory.trdnFlag = res.trdnFlag
inventory.totalOutWholeNumber = 0;
inventory.totalFragmentNumber = 0;
inventory.wholeNumber = res.inventoryWholeNumber;
inventory.fragmentNumber = res.inventoryFragmentNumber;
inventory.packagingUnit = res.packagingUnit
tableList.value.push(inventory)
})
}
interface childCheck {
id?: number,
goodsId: number,
name: string,
productionBatchCode: string,
minPackagingNumber: number,
productionDate: string
expiryDate: string,
purchaseUnitPrice: number,
wholeNumber: number,
packagingUnit: string,
fragmentNumber: number,
fragmentPrice: string,
minPackagingUnit: string;
outFragmentNumber: number;
outWholeNumber: number;
}
const addLine = (row: any) => {
post('inventory/goods/getListByIds', {idList: row.selectList}).then((list: any) => {
let children = [];
for (let i = 0; i < list.length; i++) {
let inventoryGoods = list[i];
let index = row.children ? row.children.findIndex((item: any) => item.id === inventoryGoods.id) : -1;
if (index > -1) {
children.push(row.children[index]);
} else {
let childCheck: childCheck = {
name: inventoryGoods.name,
id: inventoryGoods.id,
goodsId: inventoryGoods.goodId,
minPackagingNumber: row.minPackagingNumber,
productionBatchCode: inventoryGoods.productionBatchCode,
productionDate: inventoryGoods.productionDate,
expiryDate: inventoryGoods.expiryDate,
purchaseUnitPrice: inventoryGoods.purchaseUnitPrice,
wholeNumber: inventoryGoods.wholeNumber,
packagingUnit: inventoryGoods.packagingUnit,
fragmentNumber: inventoryGoods.fragmentNumber,
fragmentPrice: inventoryGoods.fragmentPrice,
minPackagingUnit: row.minPackagingUnit,
outFragmentNumber: inventoryGoods.outFragmentNumber,
outWholeNumber: inventoryGoods.outWholeNumber,
}
children.push(childCheck);
}
}
row.children = children;
})
}
const changeOutNumber = (row: any) => {
let totalOutWholeNumber = 0;
let totalOutFragmentNumber = 0;
for (let i = 0; i < row.children.length; i++) {
let child = row.children[i];
totalOutWholeNumber += child.outWholeNumber ? child.outWholeNumber : 0;
totalOutFragmentNumber += child.outFragmentNumber ? child.outFragmentNumber : 0;
}
row.totalOutWholeNumber = totalOutWholeNumber;
row.totalFragmentNumber = totalOutFragmentNumber;
console.log(row)
}
const save = () => {
post("inventory/apply/create", {useInfo: formData.value, data: tableList.value}).then((res: any) => {
exit()
})
}
const getUserInfo = () => {
isShow.value = true
post("manager/user/verify", null).then((res: any) => {
formData.value.useUserId = res.id;
formData.value.name = res.name;
formData.value.username = res.username;
})
}
defineExpose({getUserInfo})
</script>
<style scoped lang="scss">
.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;
}
}
.btn {
margin-top: 5px;
}
.add-panel {
position: relative;
margin-top: 24px;
height: 100%;
padding: 0 24px;
.table_content {
margin-top: 24px;
display: flex;
flex-direction: column;
.add_apply {
height: 80px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 800;
font-size: 18px;
color: #333333;
font-style: normal;
.search {
width: 50%;
}
}
.simple-table {
flex: 1;
}
}
}
.bottom {
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
padding: 0 24px;
}
</style>