2026-04-02 14:54:19 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<el-card class="hl-card">
|
|
|
|
|
|
<!-- <template #header>-->
|
|
|
|
|
|
<!-- <span>入出库单据生成</span>-->
|
|
|
|
|
|
<!-- </template>-->
|
|
|
|
|
|
<ContentWrap class="borderxx">
|
|
|
|
|
|
<!-- 搜索工作栏 -->
|
|
|
|
|
|
<el-form
|
|
|
|
|
|
class="-mb-15px"
|
|
|
|
|
|
:model="queryParams"
|
|
|
|
|
|
ref="queryFormRef"
|
|
|
|
|
|
:inline="true"
|
|
|
|
|
|
label-width="120px"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-form-item label="单据日期" prop="createTime">
|
|
|
|
|
|
<el-date-picker
|
|
|
|
|
|
v-model="queryParams.createTime"
|
|
|
|
|
|
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
|
2026-04-02 18:28:08 +08:00
|
|
|
|
class="!w-260px"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
end-placeholder="结束日期"
|
|
|
|
|
|
start-placeholder="开始日期"
|
|
|
|
|
|
type="daterange"
|
|
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="物料编号" prop="matCode">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
v-model="queryParams.matCode"
|
|
|
|
|
|
placeholder="物料编号"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
@keyup.enter="handleQuery"
|
2026-04-02 18:28:08 +08:00
|
|
|
|
class="!w-260px"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="物料名称" prop="matName">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
v-model="queryParams.matName"
|
|
|
|
|
|
placeholder="物料名称"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
@keyup.enter="handleQuery"
|
|
|
|
|
|
class="!w-260px"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="单据类型" prop="stockType">
|
|
|
|
|
|
<el-select
|
|
|
|
|
|
v-model="queryParams.stockType"
|
|
|
|
|
|
placeholder="请选择单据类型"
|
|
|
|
|
|
clearable
|
2026-04-02 18:28:08 +08:00
|
|
|
|
class="!w-260px"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="item in HeliStockTypeDict"
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="单据状态" prop="isExport">
|
|
|
|
|
|
<el-select
|
|
|
|
|
|
v-model="queryParams.isExport"
|
|
|
|
|
|
placeholder="请选择状态"
|
|
|
|
|
|
clearable
|
2026-04-02 18:28:08 +08:00
|
|
|
|
class="!w-260px"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="item in HeliStorageIsExportDict"
|
|
|
|
|
|
:key="item.value"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item>
|
|
|
|
|
|
<el-button @click="handleQuery" type="primary">
|
|
|
|
|
|
<Icon icon="ep:search" class="mr-5px" />
|
|
|
|
|
|
搜索
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<el-button @click="resetQuery">
|
|
|
|
|
|
<Icon icon="ep:refresh" class="mr-5px" />
|
|
|
|
|
|
重置
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
|
|
|
|
<el-checkbox style="margin-left: 18px" v-model="queryParams.isSameMat">
|
|
|
|
|
|
相同物料
|
|
|
|
|
|
</el-checkbox>
|
|
|
|
|
|
|
|
|
|
|
|
<el-button style="margin-left: 18px" @click="getMatCode()" type="primary" size="large">
|
|
|
|
|
|
获取编码
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
style="margin-left: 18px"
|
|
|
|
|
|
@click="submitForm()"
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
:disabled="!multipleSelection || multipleSelection.length === 0"
|
|
|
|
|
|
>
|
|
|
|
|
|
保存编码
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
<el-button
|
|
|
|
|
|
style="margin-left: 18px"
|
|
|
|
|
|
@click="generateBill()"
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
:disabled="!multipleSelection || multipleSelection.length === 0"
|
|
|
|
|
|
>
|
|
|
|
|
|
单据生成
|
|
|
|
|
|
</el-button>
|
2026-04-02 16:10:09 +08:00
|
|
|
|
<el-button style="margin-left: 18px" @click="openPnForm()" type="success" size="large">
|
2026-04-02 14:54:19 +08:00
|
|
|
|
新增物料
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
</ContentWrap>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 列表 -->
|
|
|
|
|
|
<ContentWrap>
|
|
|
|
|
|
<div class="section-title">出入库单据信息</div>
|
|
|
|
|
|
|
|
|
|
|
|
<el-table
|
|
|
|
|
|
v-loading="loading"
|
|
|
|
|
|
:data="list"
|
|
|
|
|
|
:show-overflow-tooltip="true"
|
|
|
|
|
|
class="hl-table"
|
|
|
|
|
|
ref="multipleTable"
|
|
|
|
|
|
height="calc(100vh - 410px)"
|
|
|
|
|
|
@selection-change="handleSelectionChange"
|
|
|
|
|
|
>
|
2026-04-02 18:28:08 +08:00
|
|
|
|
<el-table-column type="selection" width="40" :selectable="checkSelectable" />
|
2026-04-02 16:10:09 +08:00
|
|
|
|
<el-table-column type="index" width="60" label="序号" align="center" fixed="left" />
|
2026-04-02 14:54:19 +08:00
|
|
|
|
<el-table-column
|
|
|
|
|
|
label="单据类型"
|
|
|
|
|
|
align="center"
|
|
|
|
|
|
prop="stockMode"
|
2026-04-02 18:28:08 +08:00
|
|
|
|
min-width="100"
|
2026-04-02 16:10:09 +08:00
|
|
|
|
fixed="left"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
>
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<dict-tag :type="DICT_TYPE.HELI_STORAGE_TYPE" :value="scope.row.stockType" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column
|
|
|
|
|
|
label="单据状态"
|
|
|
|
|
|
align="center"
|
|
|
|
|
|
prop="stockMode"
|
2026-04-02 18:28:08 +08:00
|
|
|
|
min-width="100"
|
2026-04-02 16:10:09 +08:00
|
|
|
|
fixed="left"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
>
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-tag v-if="scope.row.isExport == 0 || scope.row.isExport == null" type="danger">
|
|
|
|
|
|
未生成
|
|
|
|
|
|
</el-tag>
|
|
|
|
|
|
<el-tag v-else-if="scope.row.isExport == 1" type="success">已生成</el-tag>
|
|
|
|
|
|
<el-tag v-else type="success">其他</el-tag>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column
|
|
|
|
|
|
label="单据编号"
|
|
|
|
|
|
align="center"
|
|
|
|
|
|
prop="xzdStockNo"
|
2026-04-02 18:28:08 +08:00
|
|
|
|
min-width="130"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<el-table-column label="物料编码" align="center" prop="matCode" min-width="200">
|
|
|
|
|
|
<template #default="scope">
|
2026-04-02 17:53:54 +08:00
|
|
|
|
<template v-if="scope.row.goodsType == 2 || scope.row.goodsType == 1">
|
2026-04-02 14:54:19 +08:00
|
|
|
|
<el-form-item class="mb-0px!">
|
|
|
|
|
|
<el-select
|
|
|
|
|
|
v-model="scope.row.matId"
|
|
|
|
|
|
placeholder=""
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
filterable
|
|
|
|
|
|
clearable
|
|
|
|
|
|
@change="(val) => handleMatIdChange(val, scope.row)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-option
|
|
|
|
|
|
v-for="dict in scope.row.materialDOList"
|
|
|
|
|
|
:key="dict.id"
|
|
|
|
|
|
:label="dict.code + ' ' + dict.name"
|
|
|
|
|
|
:value="dict.id"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
{{ scope.row.matCode }}
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
2026-04-02 15:33:35 +08:00
|
|
|
|
<el-table-column label="价格类型" align="center" prop="priceType" min-width="190">
|
2026-04-02 14:54:19 +08:00
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-select v-model="scope.row.priceType" placeholder="请选择" class="!w-full" clearable>
|
|
|
|
|
|
<el-option
|
2026-04-02 15:33:35 +08:00
|
|
|
|
v-for="item in getIntDictOptions(DICT_TYPE.HELI_PRICE_TYPE)"
|
2026-04-02 14:54:19 +08:00
|
|
|
|
:key="item.value"
|
|
|
|
|
|
:label="item.label"
|
|
|
|
|
|
:value="item.value"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="发票编码" align="center" prop="incoiceCode" min-width="160">
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
v-model="scope.row.incoiceCode"
|
|
|
|
|
|
placeholder="请输入发票编码"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
class="!w-full"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="物料名称" align="center" prop="matName" min-width="120" />
|
|
|
|
|
|
<el-table-column label="单价" align="center" prop="price" min-width="120" />
|
|
|
|
|
|
<el-table-column label="供应商简称" align="center" prop="brief" min-width="200" />
|
|
|
|
|
|
<el-table-column label="数量" align="center" prop="storageOkQty" min-width="140" />
|
|
|
|
|
|
<!-- <el-table-column label="单据类型" align="center" prop="stockMode" min-width="180" >-->
|
|
|
|
|
|
<!-- <template #default="scope">-->
|
|
|
|
|
|
<!-- <dict-tag :type="DICT_TYPE.HELI_STOCK_MODE" :value="scope.row.stockMode" />-->
|
|
|
|
|
|
<!-- </template>-->
|
|
|
|
|
|
<!-- </el-table-column>-->
|
|
|
|
|
|
<el-table-column label="规格型号" align="center" prop="matSpec" min-width="100" />
|
|
|
|
|
|
<el-table-column label="仓库" align="center" prop="whName" min-width="100" />
|
|
|
|
|
|
<!-- <el-table-column label="库区" align="center" prop="rgName" min-width="100" />-->
|
|
|
|
|
|
<el-table-column label="库区/库位" align="center" prop="pnName" min-width="140" />
|
|
|
|
|
|
<el-table-column label="单位" align="center" prop="matUnit" min-width="120">
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<dict-tag :type="DICT_TYPE.HELI_MATERIAL_UNIT" :value="scope.row.matUnit" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="出入库单号" align="center" prop="codeNo" min-width="180" />
|
|
|
|
|
|
<el-table-column
|
|
|
|
|
|
label="入/出库日期"
|
|
|
|
|
|
align="center"
|
|
|
|
|
|
prop="createTime"
|
|
|
|
|
|
:formatter="dateFormatter1"
|
|
|
|
|
|
min-width="170"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<!-- 分页 -->
|
|
|
|
|
|
<Pagination
|
|
|
|
|
|
:total="total"
|
|
|
|
|
|
v-model:page="queryParams.pageNo"
|
|
|
|
|
|
v-model:limit="queryParams.pageSize"
|
|
|
|
|
|
@pagination="getList"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</ContentWrap>
|
|
|
|
|
|
</el-card>
|
2026-04-02 16:10:09 +08:00
|
|
|
|
<MaterialForm ref="materialOpenFormRef" @success="getList" />
|
|
|
|
|
|
|
2026-04-02 14:54:19 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import * as StorageLogApi from '@/api/heli/xzdstoragelog'
|
|
|
|
|
|
|
|
|
|
|
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
|
|
|
|
|
|
|
|
|
|
|
import * as WarehouseApi from '@/api/heli/warehouse'
|
|
|
|
|
|
import routeParamsCache from '@/utils/routeParamsCache'
|
|
|
|
|
|
import { ElButton, ElTableColumn } from 'element-plus'
|
|
|
|
|
|
import { ref } from 'vue'
|
|
|
|
|
|
import { HeliStockTypeDict, HeliStorageStatusDict } from '@/api/heli/wmsstorage'
|
|
|
|
|
|
import { HeliStorageIsExportDict } from '@/api/heli/xzdstoragelog'
|
|
|
|
|
|
import { dateFormatter, dateFormatter1 } from '@/utils/formatTime'
|
2026-04-02 16:10:09 +08:00
|
|
|
|
import MaterialForm from "@/views/heli/material/MaterialForm.vue";
|
2026-04-02 14:54:19 +08:00
|
|
|
|
|
|
|
|
|
|
defineOptions({ name: 'Xzdstoragelog' })
|
|
|
|
|
|
|
|
|
|
|
|
const whList = ref([])
|
|
|
|
|
|
const multipleSelection = ref([])
|
|
|
|
|
|
const message = useMessage() // 消息弹窗
|
|
|
|
|
|
const { t } = useI18n() // 国际化
|
|
|
|
|
|
const exportLoading = ref(false) // 导出的加载中
|
|
|
|
|
|
const loading = ref(true) // 列表的加载中
|
|
|
|
|
|
const list = ref([]) // 列表的数据
|
|
|
|
|
|
const total = ref(0) // 列表的总页数
|
|
|
|
|
|
const queryParams = reactive({
|
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
matCode: undefined,
|
|
|
|
|
|
matName: undefined,
|
|
|
|
|
|
matType: undefined,
|
|
|
|
|
|
whId: undefined,
|
|
|
|
|
|
lotNo: undefined,
|
|
|
|
|
|
pnId: undefined,
|
|
|
|
|
|
stockNo: undefined,
|
|
|
|
|
|
stockType: undefined,
|
|
|
|
|
|
isExport: undefined,
|
|
|
|
|
|
createTime: [],
|
|
|
|
|
|
ids: []
|
|
|
|
|
|
})
|
|
|
|
|
|
const queryFormRef = ref() // 搜索的表单
|
|
|
|
|
|
const handleSelectionChange = (val) => {
|
|
|
|
|
|
// 更新 multipleSelection
|
|
|
|
|
|
multipleSelection.value = val
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 判断行是否可选择:已生成的单据不能选择
|
|
|
|
|
|
const checkSelectable = (row) => {
|
|
|
|
|
|
return row.isExport == 0 || row.isExport == null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 查询列表 */
|
|
|
|
|
|
const getList = async () => {
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
const data = await StorageLogApi.getStorageLogPage(queryParams)
|
|
|
|
|
|
list.value = data.list
|
|
|
|
|
|
total.value = data.total
|
2026-04-02 15:33:35 +08:00
|
|
|
|
// 如果没有价格类型,默认选择 1|临时暂估价
|
2026-04-02 17:53:54 +08:00
|
|
|
|
// 如果只有一个物料类型,默认选中
|
2026-04-02 15:33:35 +08:00
|
|
|
|
list.value.forEach((item) => {
|
|
|
|
|
|
if (!item.priceType) {
|
|
|
|
|
|
item.priceType = '1|临时暂估价'
|
|
|
|
|
|
}
|
2026-04-02 17:53:54 +08:00
|
|
|
|
// 如果只有一个物料类型,默认选中
|
|
|
|
|
|
if (item.materialDOList && item.materialDOList.length === 1) {
|
|
|
|
|
|
item.matId = item.materialDOList[0].id
|
|
|
|
|
|
}
|
2026-04-02 15:33:35 +08:00
|
|
|
|
})
|
2026-04-02 14:54:19 +08:00
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-04-02 16:10:09 +08:00
|
|
|
|
const materialOpenFormRef = ref()
|
|
|
|
|
|
|
|
|
|
|
|
const openPnForm = () => {
|
|
|
|
|
|
materialOpenFormRef.value.open("create")
|
|
|
|
|
|
}
|
2026-04-02 14:54:19 +08:00
|
|
|
|
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
|
|
|
const handleQuery = () => {
|
|
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
|
|
getList()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 重置按钮操作 */
|
|
|
|
|
|
const resetQuery = () => {
|
|
|
|
|
|
queryFormRef.value.resetFields()
|
|
|
|
|
|
queryParams.createTime = getDefaultDateRange()
|
|
|
|
|
|
handleQuery()
|
|
|
|
|
|
}
|
|
|
|
|
|
//仓库列表
|
|
|
|
|
|
const init_page_wh = async () => {
|
|
|
|
|
|
whList.value = await WarehouseApi.getSimpList()
|
|
|
|
|
|
}
|
|
|
|
|
|
// //库区列表
|
|
|
|
|
|
// const init_page_rg = (async ()=>{
|
|
|
|
|
|
// rgList.value = await RgApi.getSimpList()
|
|
|
|
|
|
// })
|
|
|
|
|
|
// //库位列表
|
|
|
|
|
|
// const init_page_pn = (async ()=>{
|
|
|
|
|
|
// pnList.value = await PnApi.getSimpList()
|
|
|
|
|
|
// })
|
|
|
|
|
|
const getMatCode = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const selectedList = multipleSelection.value || [] // 安全获取数据
|
|
|
|
|
|
// 1. 检查空数据
|
|
|
|
|
|
if (!selectedList || selectedList.length == null) {
|
|
|
|
|
|
message.error('提交明细不能为空,请确认')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
queryParams.ids = selectedList.map((item) => item.id)
|
|
|
|
|
|
// 保存当前的下拉框选择值和 supplierName
|
|
|
|
|
|
const currentSelections = selectedList.map((row) => ({
|
|
|
|
|
|
id: row.id,
|
|
|
|
|
|
matId: row.matId,
|
|
|
|
|
|
priceType: row.priceType,
|
|
|
|
|
|
incoiceCode: row.incoiceCode,
|
|
|
|
|
|
supplierName: row.supplierName
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
await getList()
|
|
|
|
|
|
|
|
|
|
|
|
// 恢复下拉框的值和 supplierName
|
|
|
|
|
|
currentSelections.forEach((selection) => {
|
|
|
|
|
|
const row = list.value.find((r) => r.id === selection.id)
|
|
|
|
|
|
if (row) {
|
|
|
|
|
|
row.matId = selection.matId
|
|
|
|
|
|
row.priceType = selection.priceType
|
|
|
|
|
|
row.incoiceCode = selection.incoiceCode
|
|
|
|
|
|
row.supplierName = selection.supplierName
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
queryParams.ids = []
|
|
|
|
|
|
message.success('获取成功')
|
|
|
|
|
|
emit('success')
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取失败:', error)
|
|
|
|
|
|
// message.error(`操作失败: ${error.message || "未知错误"}`);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const generateBill = async () => {
|
|
|
|
|
|
// 1. 检查是否选择了数据
|
|
|
|
|
|
if (multipleSelection.value.length === 0) {
|
|
|
|
|
|
message.warning('请选择要生成的数据')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 2. 必须选择同一类型的单据
|
|
|
|
|
|
if (
|
|
|
|
|
|
multipleSelection.value.some((row) => row.stockType !== multipleSelection.value[0].stockType)
|
|
|
|
|
|
) {
|
|
|
|
|
|
message.warning('请选择同一单据类型的数据')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-04-02 17:53:54 +08:00
|
|
|
|
// 3. 检查物料编码:根据goodsType判断
|
|
|
|
|
|
const rowWithoutMat = multipleSelection.value.find((row) => {
|
|
|
|
|
|
if (row.goodsType == 1 || row.goodsType == 2) {
|
|
|
|
|
|
return !row.matId
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return !row.matCode
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
if (rowWithoutMat) {
|
|
|
|
|
|
const tableRowIndex = list.value.findIndex((r) => r.id === rowWithoutMat.id) + 1
|
|
|
|
|
|
message.error(`行 (${tableRowIndex} )没有选择物料编码,请确认!`)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-04-02 14:54:19 +08:00
|
|
|
|
|
|
|
|
|
|
try {
|
2026-04-02 17:53:54 +08:00
|
|
|
|
// 4. 调用后端生成单据接口
|
2026-04-02 14:54:19 +08:00
|
|
|
|
await StorageLogApi.generateBill(multipleSelection.value)
|
|
|
|
|
|
message.success(`成功生成 ${multipleSelection.value.length} 条单据`)
|
2026-04-02 17:53:54 +08:00
|
|
|
|
// 5. 刷新列表,显示最新状态
|
2026-04-02 14:54:19 +08:00
|
|
|
|
await getList()
|
|
|
|
|
|
} catch (e: any) {
|
|
|
|
|
|
// 获取错误码和错误信息中的 ID 列表
|
|
|
|
|
|
let code = 0
|
|
|
|
|
|
let idStr = ''
|
|
|
|
|
|
if (typeof e === 'string') {
|
|
|
|
|
|
idStr = e
|
|
|
|
|
|
} else if (e.code) {
|
|
|
|
|
|
code = e.code
|
|
|
|
|
|
idStr = e.msg || ''
|
|
|
|
|
|
} else if (e.response?.data) {
|
|
|
|
|
|
code = e.response.data.code
|
|
|
|
|
|
idStr = e.response.data.msg || ''
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 移除 msg 中可能存在的中文后缀
|
|
|
|
|
|
idStr = idStr.replace('存在', '')
|
|
|
|
|
|
|
|
|
|
|
|
// 分割msg,获取ID数组
|
|
|
|
|
|
const msg = idStr.split(',')
|
|
|
|
|
|
// 在list中找到对应ID的序号集合(当前页的行号)
|
|
|
|
|
|
const errorIndices = msg
|
|
|
|
|
|
.map((id) => {
|
|
|
|
|
|
const index = list.value.findIndex((row) => row.id === parseInt(id))
|
|
|
|
|
|
if (index === -1) return 0 // 未找到返回0
|
|
|
|
|
|
// 使用当前页的行号
|
|
|
|
|
|
return index + 1
|
|
|
|
|
|
})
|
|
|
|
|
|
.filter((index) => index > 0) // 过滤掉未找到的
|
|
|
|
|
|
// 转换为字符串用逗号分割,errorIndices从小到大排序
|
|
|
|
|
|
errorIndices.sort((a, b) => a - b)
|
|
|
|
|
|
const errorIndicesStr = errorIndices.join(',')
|
|
|
|
|
|
|
|
|
|
|
|
// 根据不同的错误码显示不同的提示
|
|
|
|
|
|
if (code === 11115) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )没有选择物料编码,请确认!`)
|
|
|
|
|
|
} else if (code === 11111) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )存在已删除的数据,请刷新界面!`)
|
|
|
|
|
|
} else if (code === 111102) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )已生成入库单的记录,请刷新界面。`)
|
|
|
|
|
|
} else if (code === 11112) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )价格类型没有输入,请确认。`)
|
|
|
|
|
|
} else if (code === 11113) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )价格类型是'临时暂估价',发票编码不空,请确认。`)
|
|
|
|
|
|
} else if (code === 11114) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )价格类型是'3|实价',发票编码为空,请确认`)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )存在异常数据,请刷新界面。`)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 生成失败时,不清空多选状态,保留下拉框的值
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const submitForm = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const selectedList = multipleSelection.value || [] // 安全获取数据
|
|
|
|
|
|
// 1. 检查空数据
|
|
|
|
|
|
if (!selectedList || selectedList.length == null) {
|
|
|
|
|
|
message.error('提交明细不能为空,请确认')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 2.物料编码不能为空 提示 行(具体序列号)没有选择物料编码,请确认! 使用表格中的实际行号
|
2026-04-02 17:53:54 +08:00
|
|
|
|
// 根据goodsType判断:goodsType为1或2时需要选择matId,否则检查matCode
|
|
|
|
|
|
const rowWithoutMat = selectedList.find((row) => {
|
|
|
|
|
|
if (row.goodsType == 1 || row.goodsType == 2) {
|
|
|
|
|
|
return !row.matId
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return !row.matCode
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
if (rowWithoutMat) {
|
|
|
|
|
|
const tableRowIndex = list.value.findIndex((r) => r.id === rowWithoutMat.id) + 1
|
2026-04-02 14:54:19 +08:00
|
|
|
|
message.error(`行 (${tableRowIndex} )没有选择物料编码,请确认!`)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
|
// 5. 提交数据(添加超时处理)
|
|
|
|
|
|
const res = await Promise.race([
|
|
|
|
|
|
StorageLogApi.submitForm(selectedList),
|
|
|
|
|
|
new Promise((_, reject) => setTimeout(() => reject(new Error('请求超时')), 30000))
|
|
|
|
|
|
])
|
|
|
|
|
|
message.success('保存成功')
|
|
|
|
|
|
// 不立即刷新列表,保持当前的下拉框选择状态
|
|
|
|
|
|
// 用户可以通过点击搜索按钮手动刷新
|
|
|
|
|
|
await getList() // 注释掉自动刷新
|
|
|
|
|
|
// emit('success')
|
2026-04-02 15:21:43 +08:00
|
|
|
|
} catch (e: any) {
|
|
|
|
|
|
console.log(e)
|
|
|
|
|
|
// 获取错误码和错误信息中的 ID 列表
|
|
|
|
|
|
let code = 0
|
|
|
|
|
|
let idStr = ''
|
|
|
|
|
|
if (typeof e === 'string') {
|
|
|
|
|
|
idStr = e
|
|
|
|
|
|
} else if (e.code) {
|
|
|
|
|
|
code = e.code
|
|
|
|
|
|
idStr = e.msg || ''
|
|
|
|
|
|
} else if (e.response?.data) {
|
|
|
|
|
|
code = e.response.data.code
|
|
|
|
|
|
idStr = e.response.data.msg || ''
|
|
|
|
|
|
}
|
|
|
|
|
|
// 分割msg,获取ID数组
|
|
|
|
|
|
const msg = idStr.split(',')
|
|
|
|
|
|
// 在list中找到对应ID的序号集合(当前页的行号)
|
|
|
|
|
|
const errorIndices = msg
|
|
|
|
|
|
.map((id) => {
|
|
|
|
|
|
const index = list.value.findIndex((row) => row.id === parseInt(id))
|
|
|
|
|
|
if (index === -1) return 0 // 未找到返回0
|
|
|
|
|
|
// 使用当前页的行号
|
|
|
|
|
|
return index + 1
|
|
|
|
|
|
})
|
|
|
|
|
|
.filter((index) => index > 0) // 过滤掉未找到的
|
|
|
|
|
|
// 转换为字符串用逗号分割,errorIndices从小到大排序
|
|
|
|
|
|
errorIndices.sort((a, b) => a - b)
|
|
|
|
|
|
const errorIndicesStr = errorIndices.join(',')
|
|
|
|
|
|
if (code === 10086) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )存在已删除的数据,请刷新界面!`)
|
|
|
|
|
|
} else if (code === 10087) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )已生成入库单的记录,请刷新界面。`)
|
|
|
|
|
|
} else if (code === 10088) {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )没有选择物料编码,请确认!`)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
message.error(`行 (${errorIndicesStr} )存在异常数据,请刷新界面。`)
|
|
|
|
|
|
}
|
|
|
|
|
|
// console.error('获取失败:', error)
|
2026-04-02 14:54:19 +08:00
|
|
|
|
// message.error(`操作失败: ${error.message || "未知错误"}`);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 初始化 **/
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
const routeValue = ref('')
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
let params = routeParamsCache.get(route.path)
|
|
|
|
|
|
routeValue.value = route.path
|
|
|
|
|
|
if (params) {
|
|
|
|
|
|
Object.assign(queryParams, params)
|
|
|
|
|
|
}
|
|
|
|
|
|
await init_page_wh()
|
|
|
|
|
|
// await init_page_rg()
|
|
|
|
|
|
// await init_page_pn()
|
|
|
|
|
|
await getList()
|
|
|
|
|
|
})
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
|
const plainParams = JSON.parse(JSON.stringify(queryParams))
|
|
|
|
|
|
routeParamsCache.set(routeValue.value, plainParams)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('beforeunload', () => {
|
|
|
|
|
|
const plainParams = JSON.parse(JSON.stringify(queryParams))
|
|
|
|
|
|
routeParamsCache.set(routeValue.value, plainParams)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
/** 初始化 **/
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
// 设置默认日期范围:当月1号到当天
|
|
|
|
|
|
queryParams.createTime = getDefaultDateRange()
|
|
|
|
|
|
// 自动加载数据
|
|
|
|
|
|
// getList()
|
|
|
|
|
|
})
|
|
|
|
|
|
/** 获取默认日期范围 */
|
|
|
|
|
|
const getDefaultDateRange = () => {
|
|
|
|
|
|
const now = new Date()
|
|
|
|
|
|
const year = now.getFullYear()
|
|
|
|
|
|
const month = String(now.getMonth() + 1).padStart(2, '0')
|
|
|
|
|
|
const day = String(now.getDate()).padStart(2, '0')
|
|
|
|
|
|
|
|
|
|
|
|
const startDate = `${year}-${month}-01 00:00:00`
|
|
|
|
|
|
const endDate = `${year}-${month}-${day} 23:59:59`
|
|
|
|
|
|
|
|
|
|
|
|
return [startDate, endDate]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 物料编码变更处理 */
|
|
|
|
|
|
const handleMatIdChange = (val, row) => {
|
|
|
|
|
|
if (val && queryParams.isSameMat) {
|
|
|
|
|
|
// 当勾选了"相同物料"选项时,更新所有选中行的物料编码
|
2026-04-02 15:21:43 +08:00
|
|
|
|
const selectedIds = multipleSelection.value.map((item) => item.id)
|
2026-04-02 14:54:19 +08:00
|
|
|
|
|
2026-04-02 15:21:43 +08:00
|
|
|
|
list.value.forEach((item) => {
|
2026-04-02 14:54:19 +08:00
|
|
|
|
if (selectedIds.includes(item.id)) {
|
|
|
|
|
|
// 更新物料 ID
|
|
|
|
|
|
item.matId = val
|
|
|
|
|
|
// 自动设置价格类型为"1|临时暂估价"
|
|
|
|
|
|
if (!item.priceType) {
|
|
|
|
|
|
item.priceType = '1|临时暂估价'
|
|
|
|
|
|
}
|
|
|
|
|
|
// 同步更新物料编号和名称
|
2026-04-02 15:21:43 +08:00
|
|
|
|
const selectedMat = item.materialDOList?.find((m) => m.id === val)
|
2026-04-02 14:54:19 +08:00
|
|
|
|
if (selectedMat) {
|
|
|
|
|
|
item.matCode = selectedMat.code
|
|
|
|
|
|
item.matName = selectedMat.name
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
} else if (val) {
|
|
|
|
|
|
// 没有勾选"相同物料"时,只更新当前行
|
2026-04-02 15:21:43 +08:00
|
|
|
|
const selectedMat = row.materialDOList?.find((m) => m.id === val)
|
2026-04-02 14:54:19 +08:00
|
|
|
|
if (selectedMat) {
|
|
|
|
|
|
row.matCode = selectedMat.code
|
|
|
|
|
|
row.matName = selectedMat.name
|
|
|
|
|
|
}
|
|
|
|
|
|
// 自动设置价格类型为"1|临时暂估价"
|
|
|
|
|
|
if (!row.priceType) {
|
|
|
|
|
|
row.priceType = '1|临时暂估价'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|