heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/storage/StorageOutAudit.vue

1232 lines
44 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>
<!-- 出库 -->
<el-card class="hl-card" style="position: relative">
<template #header>
<span v-text="dialogTitle"></span>
</template>
<div class="abstatus">
<img src="/src/assets/imgs/status/status2.png" v-if="formData.status == 2" alt="" />
<img src="/src/assets/imgs/status/statuszf.png" v-else-if="formData.status == 3" alt="" />
<img src="/src/assets/imgs/status/status16.png" v-else-if="formData.status == 4" alt="" />
<span v-else></span>
</div>
<el-form
ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading"
:disabled="isShowBtnOther">
<!-- 基础信息 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">基础信息</span>
</template>
<el-row>
<el-col :span="8">
<el-row>
<el-col :span="24">
<el-form-item prop="name" label="出库单号">
<el-input v-model="formData.stockNo" disabled placeholder="系统自动生成" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item prop="stockInType" label="出库类型">
<el-select
v-model="formData.stockInType" clearable style="width: 100%" @change="handleStockType"
:disabled="ctrView || ctrSave">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_STORAGE_OUT_TYPE)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="projectSubName" label="子项目名称">
<el-input v-model="formData.projectSubName" :disabled="ctrView || ctrSave" readonly>
<template #append><el-button @click="openProjectForm(scope)">
<Icon icon="ep:search" class="mr-5px" />
</el-button></template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="领料人" prop="materialReceiver">
<UserSelect v-model="formData.materialReceiver" placeholder="请选择领料人" @update:newValue="handleSelectedUser" class="!w-700px" :disabled="ctrView || ctrSave"/>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="8">
<el-row>
<el-col :span="24">
<el-form-item prop="industry" label="单据状态">
<el-select v-model="formData.status" placeholder="下拉选择" clearable class="!w-700px" disabled>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_STORAGE_STATUS)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item prop="headerNo" label="上游单号">
<el-input
v-model="formData.headerNo" class="!w-700px"
:disabled="ctrView || ctrSave || enableHeadNo" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item prop="pickmode" label="领料模式" >
<el-select
v-model="formData.pickmode" placeholder="下拉选择" clearable class="!w-400px" @change="changebom"
:disabled="ctrView || ctrSave">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.PICKMODE)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="8">
<el-row>
<el-col :span="24">
<el-form-item label="单据日期" prop="createTime">
<el-date-picker
v-model="formData.createTime" value-format="x" placeholder="单据日期" disabled
class="!w-400px" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item prop="whId" label="出库仓库" required>
<el-select
v-model="formData.whId" placeholder="下拉选择" clearable class="!w-400px" @change="handleWh"
:disabled="ctrView || ctrSave">
<el-option v-for="dict in whList" :key="dict.id" :label="dict.whName" :value="dict.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item prop="pickcar" label="领料车间" >
<el-select
v-model="formData.pickcar" placeholder="下拉选择" clearable class="!w-400px"
:disabled="ctrView || ctrSave">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.PICKCAR)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="description">
<el-input
type="textarea" v-model="formData.description" show-word-limit maxlength="200" class="!w-2080px"
:disabled="ctrView || ctrSave" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<!-- 物料信息 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">物料信息</span>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-col>
<el-button
class="hl-addbutton" type="primary" size="large" :disabled="ctrView || ctrSave"
@click="openMatForm">新增</el-button>
</el-col>
<el-form
ref="matSubFormRef" :model="formData.matItemDOList" :rules="subFormRules"
v-loading="subFormLoading" label-width="0">
<el-table :data="formData.matItemDOList" class="hl-table">
<el-table-column type="index" label="序号" min-width="80" align="center" fixed />
<el-table-column prop="matCode" min-width="180" align="center">
<template #header> <span class="hl-table_header">*</span> 物料编码</template>
<template #default="scope">
<el-form-item :prop="`${scope.$index}.matCode`" :rules="subFormRules.matCode" class="mb-0px!">
<!-- <MaterialSelect v-model="scope.row.matId"
@update:newValue="handleSelectedMaterial(scope.$index, $event)"
v-bind:disabled="ctrView || ctrSave" /> -->
<el-input
class="!w-265px" placeholder="物料编码" :disabled="true || ctrView || ctrSave"
v-model="scope.row.matCode" readonly>
<!-- <template #append><el-button @click="openMatForm" disabled>
<Icon icon="ep:search" class="mr-5px" />
</el-button></template> -->
</el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="matName" label="物料名称" min-width="180" align="center" />
<el-table-column prop="matType" label="物料类型" min-width="120" align="center">
<!-- <template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_MATERIAL_TYPE" :value="scope.row.matType"
v-if="scope.row.matType ? true : false" />
</template> -->
</el-table-column>
<el-table-column prop="matSpec" label="规格/型号" min-width="120" align="center" />
<el-table-column prop="matUnit" label="系统单位" min-width="120" align="center">
<!-- <template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_MATERIAL_UNIT" :value="scope.row.matUnit"
v-if="scope.row.matUnit ? true : false" />
</template> -->
</el-table-column>
<el-table-column prop="rgId" min-width="120" align="center">
<template #header> <span class="hl-table_header">*</span>出库库区 </template>
<template #default="scope">
<el-form-item :prop="`${scope.$index}.rgId`" :rules="subFormRules.rgId" class="mb-0px!">
<el-select v-model="scope.row.rgId" placeholder="" style="width: 100%" :disabled="true">
<el-option v-for="dict in rgList" :key="dict.id" :label="dict.rg_name" :value="dict.id" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="pnId" min-width="160" align="center">
<template #header> <span class="hl-table_header">*</span>出库库位 </template>
<template #default="scope">
<el-form-item :prop="`${scope.$index}.pnId`" :rules="subFormRules.pnId" class="mb-0px!">
<el-select
v-model="scope.row.pnId" placeholder="" style="width: 100%"
:disabled="ctrView || ctrSave" @change="handlePn(scope)">
<el-option
v-for="dict in scope.row.pnlist" :key="dict.id" :label="dict.pn_name"
:value="dict.id" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="matRest" label="库存数量" min-width="120" align="center" />
<el-table-column prop="storageOkQty" min-width="120" align="center">
<template #header> <span class="hl-table_header">*</span>出库数量</template>
<template #default="scope">
<el-form-item
:prop="`${scope.$index}.storageOkQty`" :rules="subFormRules.storageOkQty"
class="mb-0px!">
<el-input v-model="scope.row.storageOkQty" :disabled="ctrView || ctrSave" />
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="price" label="库存单价" min-width="120" align="center" />
<el-table-column prop="lotNo" min-width="120" label="批次号" align="center" v-if="false" />
<el-table-column prop="projectSubName" label="子项目名称" align="center" min-width="180">
<template #default="scope">
<el-input v-model="scope.row.projectSubName" disabled>
<template #append></template>
</el-input>
</template>
</el-table-column>
<el-table-column prop="description" min-width="180" label="备注" align="center">
<template #default="scope">
<el-input v-model="scope.row.description" :disabled="ctrView || ctrSave" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100">
<template #default="scope">
<!-- <el-button v-if="!scope.row.editable" type="primary" size="small" link
@click="handleEdit(scope.$index)">
编辑
</el-button>
<el-button link v-else type="success" size="small" @click="handleSave(scope.$index)">
保存
</el-button>
<el-button link type="primary" @click="handlefuke(scope.$index, scope.row)">复制</el-button> -->
<el-button
link type="danger" size="small" @click.prevent="handleDelete2(scope.$index)"
:disabled="ctrView || ctrDelete">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
</el-card>
</el-col>
</el-row>
</el-card>
<!-- 附件信息 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">附件信息</span>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-col>
<el-upload
ref="matUploadRef" :file-list="matUploadFiles" multiple :action="uploadUrl" :headers="{
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
}" name="files" :show-file-list="false" :auto-upload="false" :data="matUploadData"
:on-change="matUploadChange" :on-error="handleError" :on-success="handleSuccess"
:before-upload="before" class="upload-file-uploader">
<el-button type="primary" :disabled="ctrView || ctrSave">
<Icon icon="ep:upload-filled" />上传
</el-button>
</el-upload>
</el-col>
<el-table
:data="formData.attachments" class="hl-table" v-loading.fullscreen.lock="uploading"
element-loading-text="附件上传中..." element-loading-background="rgba(122, 122, 122, 0.6)">
<el-table-column prop="name" label="文件名称" align="center">
<!-- <template #default="scope">
<a :href="scope.row.url" target="_blank" style="color: #409eff">{{ scope.row.name }} </a>
</template> -->
</el-table-column>
<el-table-column prop="createTime" align="center" label="上传日期" :formatter="dateFormatter" />
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link type="danger" size="small" :disabled="ctrView || ctrDelete"
@click="handleDeleteAttachment(scope.$index, scope.row.businessFileType)">
删除
</el-button>
<el-button
link type="primary" size="small" :disabled="ctrView || ctrDelete"
@click="downloadAttachment(scope.row.name, scope.row.url)">
下载
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</el-card>
<!-- 系统信息 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">系统信息</span>
<el-button @click="() => router.go(-1)" size="large" style="margin-left: 5rem">取 消</el-button>
<el-button @click="handleStatus(4)" type="success" v-if="btnok " size="large">审核</el-button>
</template>
<el-row justify="center">
<el-col :span="8">
<el-form-item prop="creator" label="创建人">
{{ userList.find((user) => user.id == formData.creator)?.nickname }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="createTime" label="创建时间">
{{ formatDate(formData.createTime, 'YYYY-MM-DD HH:mm') }}
</el-form-item>
</el-col>
</el-row>
<el-row justify="center">
<el-col :span="8">
<el-form-item prop="outbound" label="出库人">
{{ userList.find((user) => user.id == formData.outbound)?.nickname }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="outboundTime" label="出库时间">
{{ formatDate(formData.outboundTime, 'YYYY-MM-DD HH:mm') }}
</el-form-item>
</el-col>
</el-row>
<el-row justify="center">
<el-col :span="8">
<el-form-item prop="cancel" label="作废人">
{{ userList.find((user) => user.id == formData.cancel)?.nickname }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="cancelTime" label="作废时间">
{{ formatDate(formData.cancelTime, 'YYYY-MM-DD HH:mm') }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
<!-- <div class="hl-footer text-center">-->
<!-- -->
<!-- </div>-->
</el-card>
<el-dialog v-model="centerDialogVisible" title="提示" width="30%" center>
<span>
作废该单据后无法复原,请确认是否作废?
</span>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="deleteStorage()">
确认
</el-button>
<el-button @click="centerDialogVisible = false">取消</el-button>
</span>
</template>
</el-dialog>
<!-- 表单弹窗:物料列表 -->
<materials ref="matOpenFormRef" @success="getList" />
<!-- 表单弹窗:物料列表 -->
<projects ref="proOpenFormRef" @success="getProject" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { dateFormatter, formatDate } from '@/utils/formatTime'
import type { UploadUserFile } from 'element-plus'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as StorageApi from '@/api/heli/storage'
import * as StorageMatApi from '@/api/heli/storagemat'
import { getAccessToken, getTenantId } from '@/utils/auth'
import { useUserStore } from '@/store/modules/user'
import MaterialSelect from '@/views/heli/hlvuestyle/materialSelect.vue'
import * as MaterialApi from '@/api/heli/material'
import * as WarehouseApi from '@/api/heli/warehouse'
import * as RgApi from '@/api/heli/rg'
import * as PnApi from '@/api/heli/pn'
import { deleteFile, downloadFile, getFilePage } from '@/api/infra/file'
import download from '@/utils/download'
import * as UserApi from '@/api/system/user'
import materials from './materials.vue'
import projects from './subproject.vue'
import UserSelect from "@/views/heli/hlvuestyle/userSelect.vue";
const reload: any = inject('reload')
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const { query } = useRoute()
const router = useRouter()
const centerDialogVisible = ref(false)
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
id: undefined,
stockType: 2,
stockInType: undefined,
projectSubName:undefined,
pickmode:undefined,
pickcar:undefined,
projectNo:undefined,
stockOutType: undefined,
stockNo: undefined,
headerNo: undefined,
description: undefined,
status: 1,
whId: undefined,
creator: undefined,
createTime: undefined,
keeper: undefined,
keeperTime: undefined,
outbound: undefined,
outboundTime: undefined,
cancel: undefined,
cancelTime: undefined,
matItemDOList: [],
attachments: [],
beforeStatus:undefined,
})
const formRules = reactive({
// name: [{ required: true, message: '模具类型不能为空', trigger: 'blur' }],
status: [{ required: true, message: '启用状态不能为空', trigger: 'blur' }],
stockInType: [{ required: true, message: '出库类型不能为空', trigger: 'blur' }],
// projectSubName: [{ required: true, message: '子项目名称不能为空', trigger: 'blur' }],
// pickmode: [{ required: true, message: '领料模式不能为空', trigger: 'blur' }],
// pickcar: [{ required: true, message: '领料车间不能为空', trigger: 'blur' }],
whId: [{ required: true, message: '出库仓库不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
const matSubFormRef = ref() //子表单 Ref
const subFormLoading = ref(false) // 子表单的加载中
const subFormRules = reactive({
matId: [{ required: true, message: '物料不能为空', trigger: 'blur' }],
matCode: [{ required: true, message: '物料编码不能为空', trigger: 'blur' }],
rgId: [{ required: true, message: '库区不能为空', trigger: 'blur' }],
pnId: [{ required: true, message: '库位不能为空', trigger: 'blur' }],
storageOkQty: [{ required: true, message: '出库数量不能为空', trigger: 'blur' }]
})
const matOpenFormRef = ref()
const proOpenFormRef = ref()
const openMatForm = () => {
// if (formData.value.whId == undefined || formData.value.whId == '') {
// message.alertWarning('请选择入库仓库')
// return
// }
// formData.value.whId
if(formData.value.pickmode==1){
matOpenFormRef.value.open(formData.value.projectNo, 'bomfind')
}else{
matOpenFormRef.value.open(formData.value.whId, 'out')
}
}
const openProjectForm = (scope) => {
proOpenFormRef.value.open(scope)
}
const handleSelectedUser = (newValue: any) => {
formData.value.materialReceiver = newValue?.id
}
const getList = async (arrMat) => {
arrMat.forEach((row) => {
if (
formData.value.matItemDOList.filter(
(item) =>
item.matId == row.id &&
item.whId == row.whId &&
item.rgId == row.rgId &&
item.pnId == row.pnId
).length == 0
) {
if(row.whId1){
row.matId = row.matId
}else{
row.matId = row.id
}
row.projectNo = formData.value.projectNo
row.projectSubName =formData.value.projectSubName
row.pnlist = ref([])
row.pnlist = pnList.value.filter((pn) => pn.wh_id == row.whId && pn.rg_id == row.rgId)
if (row.pnlist.length == 0) {
row.rgId = ''
row.pnId = ''
row.matRest = 0
row.projectNo = formData.value.projectNo
row.projectSubName =formData.value.projectSubName
}
formData.value.matItemDOList.push(row)
}
})
}
const getProject = async (pro, scope) => {
formData.value.projectSubName=pro.projectSubName
formData.value.projectNo=pro.projectSubId
// formData.value.matItemDOList.forEach(
// (item) => {
// if (item.matId == scope.value.row.matId && item.whId == scope.value.row.whId && item.rgId == scope.value.row.rgId && item.pnId == scope.value.row.pnId) {
// item.projectNo = pro.projectSubId
// item.projectSubName = pro.projectSubName
// }
// }
// )
}
// 根据出库类型显示上游单号
const enableHeadNo = ref(false)
const handleStockType = async (typeid) => {
if(typeid==5){
// 当 typeid 等于 5 时,启用验证规则
formRules.projectSubName = [{ required: true, message: '子项目名称不能为空', trigger: 'blur' }]
formRules.pickmode = [{ required: true, message: '领料模式不能为空', trigger: 'blur' }]
formRules.pickcar = [{ required: true, message: '领料车间不能为空', trigger: 'blur' }]
} else {
// 当 typeid 不等于 5 时,移除验证规则
delete formRules.projectSubName
delete formRules.pickmode
delete formRules.pickcar
}
formData.value.headerNo = ''
if (typeid == 1) {
enableHeadNo.value = false
} else {
enableHeadNo.value = true
}
}
const deleteData = ref<StorageApi.StorageVO>();
const deleteStorage = async() =>{
await StorageApi.updateStorage(deleteData.value)
deleteData.value.cancel = useUserStore().getUser.id
commonResult = 'common.updateSuccess'
await StorageApi.updateStorageStatus(deleteData.value)
message.success(t('common.updateSuccess'))
query.id = formData.value.id
query.type = 'update'
if (sumbefore.value == 0) {
reload()
}
centerDialogVisible.value = false
}
const handleStatus = async (num) => {
formData.value.status = num
const data = formData.value as unknown as StorageApi.StorageVO
if (num == 2) {
// 校验表单
await formRef.value.validate()
if (formData.value.matItemDOList.length === 0) {
message.alertWarning('请添加物料信息!')
return
}
// 校验子表单
try {
await matSubFormRef.value.validate()
} catch (e) {
return
}
var repeatItem = []
formData.value.matItemDOList.forEach(item => {
if (formData.value.matItemDOList.filter((mat) => mat.matId == item.matId && mat.pnId == item.pnId).length > 1) {
var tmpCode = "[" + item.matCode + "]"
if (repeatItem.indexOf(tmpCode) < 0) {
repeatItem.push(tmpCode)
}
}
})
if (repeatItem.length > 0) {
message.alertWarning(
'物料编码' + repeatItem.join(',') + '出库库位存在多行数据,请修改,避免重复出库'
)
return
}
//获取最新库存信息
const matCurrentData = await StorageMatApi.getStorageMatList(0)
var hasRestNum = true
formData.value.matItemDOList.forEach((rest) => {
if (
matCurrentData.find(
(mat) =>
mat.matId == rest.matId &&
mat.pnId == rest.pnId &&
mat.matRest < Number(rest.storageOkQty)
) !== undefined ||
rest.storageOkQty.length == 0
) {
hasRestNum = false
}
})
if (!hasRestNum) {
message.alertWarning('物料库存不足')
return
}
// 提示用户是否保存出库信息
await message.confirm('确认提交出库信息?')
//保存表单数据
await saveFormData()
data.outbound = useUserStore().getUser.id
} else if(num ==3) {
deleteData.value = data;
centerDialogVisible.value = true;
}else{
await StorageApi.updateStorageok(data)
if(formData.value.stockOutType == 1){
const dataMats = formData.value.matItemDOList as unknown as StorageMatApi.StorageMatVO[]
await StorageMatApi.createStorageMatBatch(dataMats, formData.value.id)
}
}
if(num != 3){
await StorageApi.updateStorageStatus(data)
message.success(t('common.updateSuccess'))
query.id = formData.value.id
query.type = 'update'
if (sumbefore.value == 0) {
reload()
}
}
}
// ====================附件信息 开始=======================================
const uploadUrl = ref(import.meta.env.VITE_UPLOAD_BATCH_URL)
const matUploadRef = ref()
const matUploadFiles = ref<UploadUserFile[]>([])
const uploading = ref(false)
const matUploadData = ref({
businessType: 'STORAGE',
businessId: formData.value.id,
businessFileType: 'MATERIAL'
})
const matUploadChange = (file, files) => {
matUploadFiles.value = files
refreshAttachments(files, 'MATERIAL')
}
// 记录待上传、成功上传及失败上传的文件数量
const sumbefore = ref(0)
const successfulUploadsCount = ref(0)
const failedUploadsCount = ref(0)
const failedAttachments = ref<UploadUserFile[]>([])
const failedAttachmentsName = ref()
// 处理单个文件上传成功的情况
const handleSuccess = (response: any, file: UploadUserFile) => {
successfulUploadsCount.value++
// 更新附件信息等其他逻辑...
// console.log('上传成功数量', successfulUploadsCount.value)
}
// 处理单个文件上传失败的情况
const handleError = (error: Error, file: UploadUserFile) => {
failedUploadsCount.value++
if (failedUploadsCount.value > 0) {
// 当有上传错误时
// 将失败的附件添加到failedAttachments.value数组中
failedAttachments.value.push(file)
failedAttachmentsName.value = failedAttachments.value.map((value) => value.name)
}
// console.log('上传失败数量', failedUploadsCount.value)
}
// 文件上传前的钩子
const before = (rawFile) => {
sumbefore.value++
}
const refreshAttachments = (files, type) => {
formData.value.attachments = formData.value.attachments.filter((value) => value.id)
// 避免重复添加
const newFiles = files.filter(
(file) => !formData.value.attachments.some((att) => att.name === file.name)
)
for (let i = 0; i < newFiles.length; i++) {
let file = newFiles[i]
file.businessFileType = type
file.createTime = new Date()
formData.value.attachments.push(file)
}
// 排序
formData.value.attachments.sort((v1, v2) => v1.createTime - v2.createTime)
// 文件上传一遍 上传总数等于要上传文件时 刷新页面
const sum = successfulUploadsCount.value + failedUploadsCount.value
// console.log('上传总数', sum)
// console.log('要上传文件数量', sumbefore.value)
if (sumbefore.value !== sum && sumbefore.value !== 0 && sum !== 0) {
// console.log('要上传文件数量不等于上传总数时等待',uploading.value)
uploading.value = true
} else if (sum == sumbefore.value && sumbefore.value > 0 && sum > 0) {
// console.log('要上传文件数量等于上传总数 刷新页面并给出提示')
if (failedUploadsCount.value > 0) {
ElMessageBox.alert(
// 使用错误信息作为提示内容
`文件名为:${failedAttachmentsName.value.join(' / ')}上传失败`,
`文件格式不正确或网络问题 请您稍后再试`,
{
dangerouslyUseHTMLString: false,
confirmButtonText: '知道了',
center: true
}
)
}
reload()
uploading.value = false
}
}
// 删除附件
const handleDeleteAttachment = async (index, type) => {
const deletedAttachments = formData.value.attachments.splice(index, 1)
for (let i = 0; i < deletedAttachments.length; i++) {
const attachment = deletedAttachments[i]
if (attachment.id) {
// 清理已上传文件
await deleteFile(attachment.id)
}
// 清理待上传文件
matUploadFiles.value = matUploadFiles.value.filter((file1) => {
return file1.name != attachment.name || file1.businessFileType != type
})
}
}
// 下载文件
const downloadAttachment = async (name, url) => {
if (url) {
const baseUrl = import.meta.env.VITE_BASE_URL;
url =baseUrl+'/admin-api/'+ url.split('/admin-api/')[1]; const data = await downloadFile(url)
download.any(data, name)
}
}
// ====================附件信息 结束=======================================
var commonResult = ''
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const saveFormData = async () => {
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as StorageApi.StorageVO
if (query.type === 'create') {
//库存信息保存
formData.value.id = await StorageApi.createStorage(data)
commonResult = 'common.createSuccess'
} else {
await StorageApi.updateStorage(data)
commonResult = 'common.updateSuccess'
}
//物料信息保存
formData.value.matItemDOList.forEach((item) => {
item.stockId = formData.value.id
item.whId = formData.value.whId
})
const dataMats = formData.value.matItemDOList as unknown as StorageMatApi.StorageMatVO[]
await StorageMatApi.createStorageMatBatch(dataMats, formData.value.id)
if (formData.value.attachments != undefined && formData.value.attachments.length > 0) {
//附件信息保存
matUploadData.value.businessId = formData.value.id
await matUploadRef.value!.submit()
}
await initStatus(formData.value.status)
message.success(t(commonResult))
} finally {
formLoading.value = false
}
}
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
var repeatItem = []
formData.value.matItemDOList.forEach(item => {
if (formData.value.matItemDOList.filter((mat) => mat.matId == item.matId && mat.pnId == item.pnId).length > 1) {
var tmpCode = "[" + item.matCode + "]"
if (repeatItem.indexOf(tmpCode) < 0) {
repeatItem.push(tmpCode)
}
}
})
if (repeatItem.length > 0) {
message.alertWarning(
'物料编码' + repeatItem.join(',') + '出库库位存在多行数据,请修改,避免重复出库'
)
return
}
// if (formData.value.matItemDOList.length === 0) {
// message.alertWarning('请添加物料信息!')
// return
// }
// 校验子表单
try {
await matSubFormRef.value.validate()
} catch (e) {
return
}
//获取最新库存信息
const matCurrentData = await StorageMatApi.getStorageMatList(0)
var hasRestNum = true
formData.value.matItemDOList.forEach((rest) => {
if (
matCurrentData.find(
(mat) =>
mat.matId == rest.matId &&
mat.pnId == rest.pnId &&
mat.matRest < Number(rest.storageOkQty)
) !== undefined ||
rest.storageOkQty.length == 0
) {
hasRestNum = false
}
})
if (!hasRestNum) {
message.alertWarning('物料库存不足')
return
}
// // 提示用户是否保存出库信息
// await message.confirm('确认保存出库信息?')
//保存表单数据
await saveFormData()
// 成功后刷新
query.id = formData.value.id
query.type = 'update'
if (sumbefore.value == 0) {
reload()
}
}
const onAddItem = () => {
if (formData.value.whId) {
const newData = {
// 新数据的属性
stockId: 0,
matId: '',
matName: '',
matCode: '',
matType: '',
matSpec: '',
matUnit: '',
whId: '',
rgId: '',
pnId: '',
pnlist: ref([]),
storageOkQty: '',
lotNo: '',
description: '',
productBomItemValueDOList: [],
matList: matList.value
}
formData.value.matItemDOList.push(newData)
} else {
message.alertWarning('请选择出库仓库')
}
}
//删除新增物料信息
const handleDelete2 = (index: number) => {
formData.value.matItemDOList.splice(index, 1)
}
//仓库全数据
const whList = ref([])
//库区全数据
const rgList = ref([])
//库位全数据
const pnList = ref([])
const handleWh = async (wid) => {
formData.value.matItemDOList = []
formData.value.rgId = ''
// 获得库区列表
rgList.value = (await RgApi.getSimpList()).filter((rg) => rg.wh_id == wid)
// 获得库位列表
pnList.value = (await PnApi.getSimpList()).filter((pn) => pn.wh_id == wid)
//await getMatList()
}
// const changebom = async (pickmode) => {
// debugger
// if(pickmode==1){
// }
// }
const getMatList = async (name) => {
// 获得物料列表
let matParams = {
pageNo: 1,
pageSize: 10,
status: '1'
}
if (name.length > 0) {
matParams.name = name
}
//const matLastRemoteData = await StorageMatApi.getStorageMatList(0)
const dataMat = await MaterialApi.getMaterialPage(matParams)
matList.value = dataMat.list
// matList.value = dataMat.list.filter(
// (item) =>
// matLastRemoteData.find(
// (fish) => fish.matId === item.id && fish.whId == formData.value.whId
// ) !== undefined
// )
}
const handlePn = async (scope) => {
scope.row.matList = matList.value
// var repeatItem = formData.value.matItemDOList.filter(
// (mat) => mat.matId == scope.row.matId && mat.pnId == scope.row.pnId
// )
// if (repeatItem.length > 1) {
// message.alertWarning(
// '物料编码[' + repeatItem[0].matCode + ']出库库位存在多行数据,请修改,避免重复出库'
// )
// return
// }
if (
matLastData.value.find(
(item) =>
item.matId === scope.row.matId &&
item.whId == formData.value.whId &&
item.pnId == scope.row.pnId
)
) {
const matVo = matLastData.value.find(
(item) =>
item.matId === scope.row.matId &&
item.whId == formData.value.whId &&
item.pnId == scope.row.pnId
)
// scope.row.matId = matVo.matId
// scope.row.matName = matVo.matName
// scope.row.matCode = matVo.matCode
// scope.row.matSpec = matVo.matSpec
// scope.row.matType = matVo.materialType
// scope.row.matUnit = matVo.matUnit
scope.row.rgId = matVo.rgId
scope.row.pnId = matVo.pnId
scope.row.matRest = matVo.matRest
// scope.row.storageOkQty = matVo.storageOkQty
// scope.row.lotNo = matVo.lotNo
// scope.row.description = matVo.description
} else {
scope.row.rgId = ''
scope.row.matRest = '0'
message.alertWarning('当前库位无库存数量可出库')
}
}
const matSelectLoading = ref(false)
const remoteMatNameSearch = async (name) => {
matSelectLoading.value = true
// 获得物料列表
await getMatList(name)
matSelectLoading.value = false
}
const handleMatName = async (scope, matid) => {
scope.row.matId = scope.row.matList.find((item) => item.id === matid)?.id
scope.row.matName = scope.row.matList.find((item) => item.id === matid)?.name
scope.row.matCode = scope.row.matList.find((item) => item.id === matid)?.code
scope.row.matSpec = scope.row.matList.find((item) => item.id === matid)?.spec
scope.row.matType = scope.row.matList.find((item) => item.id === matid)?.materialType
scope.row.matUnit = scope.row.matList.find((item) => item.id === matid)?.unit
scope.row.rgId = ''
scope.row.pnId = ''
if (matid.length == 0) {
}
scope.row.pnlist = pnList.value.filter(
(pn) =>
pn.wh_id == formData.value.whId &&
matLastData.value.filter((mat) => mat.matId == matid && mat.pnId == pn.id).length > 0
)
}
const matLastData = ref([])
// 按钮控制
const ctrView = ref(false)
const ctrSave = ref(false)
const ctrCancel = ref(true)
const ctrDelete = ref(false)
const btnSave = ref(true)
const btnCancel = ref(false)
const btnok = ref(true)
// 根据页面动作和数据状态控制按钮输入框信息
const initStatus = async (status) => {
switch (status) {
case 1:
ctrView.value = false
ctrSave.value = false
ctrCancel.value = true
ctrDelete.value = false
btnSave.value = true
btnCancel.value = false
break
case 2:
ctrView.value = false
ctrSave.value = true
ctrCancel.value = false
ctrDelete.value = true
btnSave.value = false
btnCancel.value = true
break
case 3:
ctrView.value = true
ctrSave.value = true
ctrCancel.value = true
ctrDelete.value = true
btnSave.value = false
btnCancel.value = false
btnok.value=false
break
case 4:
ctrView.value = true
ctrSave.value = false
ctrCancel.value = true
ctrDelete.value = false
btnSave.value = false
btnCancel.value = false
btnok.value=false
break
default:
break
}
// 查看页面时可操作控件禁用
if (query.type === 'review') {
ctrView.value = true
ctrSave.value = true
ctrCancel.value = true
ctrDelete.value = true
btnSave.value = false
btnok.value=false
// if(formData.value.status == 4){
// btnCancel.value = true
// }else{
// btnCancel.value = false
// }
}
}
const matList = ref<MaterialApi.MaterialVO[]>([]) // 物料列表
const matEditList = ref<MaterialApi.MaterialVO[]>([]) // 物料列表
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
const matSimpList = ref([]) // 物料基本信息列表
const matSimpVirtualList = ref([]) // 物料基本信息列表
/** 初始化 **/
onMounted(async () => {
// 页面标题展示
dialogTitle.value = query.type === 'review' ? '查看' : t('action.' + query.type)
//- 获取仓库全数据
whList.value = await WarehouseApi.getWarehouseSimpList()
formData.value.whId = Math.min.apply(Math, whList.value.map(function(i) {return i.id}));
//获取状态为启用的物料信息
await getMatList('')
// // 获取当前最新库存信息
// matLastData.value = await StorageMatApi.getStorageMatList(0)
// 编辑时获取入库单据信息,包括基础信息、物料信息、附件信息
if (query.id) {
// 获取原始物料信息
matSimpList.value = await MaterialApi.getSimpList()
matSimpVirtualList.value = await MaterialApi.getSimpVirtualList()
matEditList.value = matSimpList.value //matSimpList.value.filter( mat => matLastData.value.filter( row => row.matId == mat.id).length>0)
// 获取库存信息
formData.value = await StorageApi.getStorage(query.id)
if (formData.value.vmatName) {
matEditList.value = matSimpVirtualList.value
}
// 页面控件可视初始化
await initStatus(formData.value.status)
// 获得库区列表
const dataRgList = await RgApi.getSimpList()
rgList.value = dataRgList.filter((rg) => rg.wh_id == formData.value.whId)
// 获得库区列表
const dataPnList = await PnApi.getSimpList()
pnList.value = dataPnList.filter((pn) => pn.wh_id == formData.value.whId)
// 获取库存物料列表信息
const queryParamsMat = reactive({
pageNo: 1,
pageSize: 99,
stockId: query.id
})
const dataMats = await StorageMatApi.getStorageMatPage(queryParamsMat)
formData.value.matItemDOList = dataMats
var matTypes = getIntDictOptions(DICT_TYPE.HELI_MATERIAL_TYPE)
var matUnits = getIntDictOptions(DICT_TYPE.HELI_MATERIAL_UNIT)
// 填充物料原始信息
formData.value.matItemDOList.forEach((item) => {
item.matId = matEditList.value.find((record) => record.id === item.matId)?.id
item.matCode = matEditList.value.find((record) => record.id === item.matId)?.code
item.matName = matEditList.value.find((record) => record.id === item.matId)?.name
item.matSpec = matEditList.value.find((record) => record.id === item.matId)?.spec
item.matType = matTypes.find( op => op.value == matEditList.value.find((record) => record.id === item.matId)?.material_type)?.label
item.matUnit = matUnits.find( op => op.value == matEditList.value.find((record) => record.id === item.matId)?.unit)?.label//matSimpList.value.find((record) => record.id === item.matId)?.unit
// item.matRest = matLastData.value.find(
// (row) => row.matId == item.matId && row.pnId == item.pnId
// )?.matRest
// console.log('ss'+item.matRest);
// item.matRest = item.matRest == undefined || item.matRest.length == 0 ? 0 : item.matRest
item.pnlist = pnList.value.filter((pn) => pn.wh_id === item.whId)
item.matList = matEditList.value.filter((record) => record.id === item.matId)
})
// matList.value = matSimpList.value.filter( mat => matLastData.value.filter( row => row.matId == mat.id).length>0 || formData.value.matItemDOList.filter(fan => fan.matId == mat.id).length>0)
// if(matList.value.length == 0){
// matList.value = matSimpVirtualList.value.filter( mat => matLastData.value.filter( row => row.matId == mat.id).length>0 || formData.value.matItemDOList.filter(fan => fan.matId == mat.id).length>0)
// }
// 附件信息
let attParams = {
pageNo: 1,
pageSize: 99,
businessId: query.id,
businessType: 'STORAGE'
}
formData.value.attachments = (await getFilePage(attParams)).list
}
//用户信息,用于底部数据展示
userList.value = await UserApi.getSimpleUserList()
formData.value.beforeStatus = formData.value.status;
})
//接收物料传递的数据
const handleSelectedMaterial = (currentIndex: number, newValue: any) => {
// console.log(currentIndex,'接收物料对应的数据:', newValue)
formData.value.matItemDOList[currentIndex].matId = newValue?.id
formData.value.matItemDOList[currentIndex].matName = newValue?.name
formData.value.matItemDOList[currentIndex].matCode = newValue?.code
formData.value.matItemDOList[currentIndex].matSpec = newValue?.spec
formData.value.matItemDOList[currentIndex].matType = newValue?.materialType
formData.value.matItemDOList[currentIndex].matUnit = newValue?.unit
formData.value.matItemDOList[currentIndex].rgId = ''
formData.value.matItemDOList[currentIndex].pnId = ''
formData.value.matItemDOList[currentIndex].pnlist = pnList.value.filter(
(pn) =>
pn.wh_id == formData.value.whId &&
matLastData.value.filter((mat) => mat.matId == newValue?.id && mat.pnId == pn.id).length > 0
)
}
</script>
<style>
a {
color: #409eff;
text-decoration: none;
}
</style>