Commit 681244f3 by wusiyi

feat: 备货计划页面1000860

parent 38d2938d
...@@ -10,6 +10,8 @@ import { ...@@ -10,6 +10,8 @@ import {
AnyObject, AnyObject,
InterProductList, InterProductList,
ExportInWarehouseInfo, ExportInWarehouseInfo,
stockingPlanSearchForm,
InterStackingPlanDetail
} from '@/types/api/warehouse' } from '@/types/api/warehouse'
export interface LogListData { export interface LogListData {
createTime: string createTime: string
...@@ -596,3 +598,96 @@ export function deleteWarehouseOutRecordApi(ids: string) { ...@@ -596,3 +598,96 @@ export function deleteWarehouseOutRecordApi(ids: string) {
}, },
) )
} }
// 备货计划 树状图
export function getStackingPlanStatusTree() {
return axios.get<never, BaseRespData<InterWarehouseTree[]>>(
'factoryStockingPlanRecord/status_tree',
)
}
// 备货计划 列表
export function getStackingPlanListPage(data: stockingPlanSearchForm, currentPage: number,
pageSize: number,) {
return axios.post<never, BasePaginationData<InterWarehousePage>>(
'factoryStockingPlanRecord/list_page',
{
...data,
currentPage,
pageSize,
},
)
}
// 备货计划 新增
export function addStackingPlanApi(data: InterWarehouseDetail) {
return axios.post<never, BaseRespData<never>>(
'factoryStockingPlanRecord/add',
data,
)
}
// 备货计划 编辑
export function updateStackingPlanApi(data: InterStackingPlanDetail) {
return axios.post<never, BaseRespData<never>>(
'factoryStockingPlanRecord/update',
data,
)
}
// 备货计划 详情
export function getStackingPlanDetailApi(id: number | undefined) {
return axios.get<never, BaseRespData<InterStackingPlanDetail>>(
'factoryStockingPlanRecord/get',
{
params: {
id,
},
},
)
}
// 备货计划 日志
export function getStackingPlanLogApi(stockingPlanRecordId?: number) {
return axios.get<never, BaseRespData<LogListData[]>>(
`factoryStockingPlanRecord/log/${stockingPlanRecordId}`,
)
}
// 备货计划 驳回
export function rejectStackingPlanApi({
list,
rejectReason,
status,
}: {
list: WarehouseParams[]
rejectReason: string
status: string
}) {
return axios.post<never, BaseRespData<never>>(
'factoryStockingPlanRecord/reject',
{
list,
rejectReason,
status,
},
)
}
// 备货计划 删除
export function deleteStackingPlanApi(ids: string) {
return axios.get<never, BaseRespData<never>>(
'factoryStockingPlanRecord/delete',
{
params: { ids },
},
)
}
// 备货计划 审核
export function auditStackingPlanApi(data: WarehouseParams) {
return axios.post<never, BaseRespData<never>>(
'factoryStockingPlanRecord/audit',
{ data },
)
}
\ No newline at end of file
...@@ -118,11 +118,17 @@ export interface ILocation { ...@@ -118,11 +118,17 @@ export interface ILocation {
locationCode?: string | null locationCode?: string | null
} }
export interface stockingPlanSearchForm { // 备货计划 查询
warehouseId?: number | string export interface stockingPlanSearchForm extends InterWarehouseBase {
warehouseSku?: string
outNo?: string
timeType?: string timeType?: string
startTime?: string startDate?: string
endTime?: string endDate?: string
dateStr?: string
warehouseSku?: string
}
// 备货计划 新增编辑
export interface InterStackingPlanDetail extends InterWarehouseDetail {
boxSum?: number
checkBoxSum?: number
} }
...@@ -30,23 +30,20 @@ ...@@ -30,23 +30,20 @@
<splitDiv size="50"> <splitDiv size="50">
<template #top> <template #top>
<div class="header-filter-form"> <div class="header-filter-form">
<ElForm :model="searchForm" inline ref="searchFormRef"> <ElForm ref="searchFormRef" :model="searchForm" inline>
<ElFormItem label="仓库"> <ElFormItem>
<ElSelect <el-select
v-model="searchForm.warehouseId" v-model="searchForm.dateStr"
clearable clearable
placeholder="请选择仓库" :teleported="false"
style="width: 160px" placeholder="时间类型"
style="width: 100px; margin-right: 5px"
> >
<ElOption <el-option value="createTime" label="创建时间" />
v-for="item in warehouseList" <el-option value="auditTime" label="审核时间" />
:key="item.id" <el-option value="deliveryTime" label="发货时间" />
:label="item.name" <el-option value="warehouseTime" label="入库时间" />
:value="item.id" </el-select>
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="出库时间">
<el-date-picker <el-date-picker
v-model="tradingTime" v-model="tradingTime"
:shortcuts="pickerOptions.shortcuts" :shortcuts="pickerOptions.shortcuts"
...@@ -63,43 +60,64 @@ ...@@ -63,43 +60,64 @@
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
/> />
</ElFormItem> </ElFormItem>
<ElFormItem label="出库单号"> <ElFormItem label="备货单号">
<ElInput <ElInput
v-model.trim="searchForm.outNo" v-model.trim="searchForm.inNo"
clearable clearable
placeholder="请输入出库单号" placeholder="请输入备货单号"
style="width: 160px" style="width: 160px"
/> />
</ElFormItem> </ElFormItem>
<ElFormItem label="备货仓库">
<ElSelect
v-model="searchForm.warehouseId"
clearable
placeholder="请选择仓库"
style="width: 160px"
>
<ElOption
v-for="item in warehouseList"
:key="item.id"
:label="item.name"
:value="item.id"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem style="margin-right: 10px" label="库存SKU"> <ElFormItem style="margin-right: 10px" label="库存SKU">
<ElInput <ElInput
v-model.trim="searchForm.warehouseSku" v-model="searchForm.warehouseSku"
clearable clearable
placeholder="请输入库存SKU" placeholder="请输入库存SKU"
style="width: 160px" style="width: 160px"
/> />
</ElFormItem> </ElFormItem>
<ElFormItem style="margin-right: 10px" label="出库单ID"> <ElFormItem style="margin-right: 10px" label="物流单号">
<ElInput <ElInput
v-model.trim="searchForm.id" v-model.trim="searchForm.shipmentNumber"
clearable clearable
placeholder="请输入出库单ID" placeholder="请输入物流单号"
style="width: 160px" style="width: 160px"
/> />
</ElFormItem> </ElFormItem>
<ElFormItem> <ElFormItem>
<ElButton type="primary" @click="search" ref="searchBtnRef" <ElButton ref="searchBtnRef" type="primary" @click="search">
>查询</ElButton 查询
> </ElButton>
</ElFormItem> </ElFormItem>
<ElFormItem> <ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton> <ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem> </ElFormItem>
<ElFormItem>
<el-button type="success" @click="handleExport">
导出</el-button
>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'"> <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="primary" @click="addDialog(1, null)"> <el-button type="primary" @click="addDialog(1, null)">
新增 新增
</el-button> </el-button>
</ElFormItem> </ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'"> <ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="danger" @click="rejectedInRecord"> <el-button type="danger" @click="rejectedInRecord">
驳回 驳回
...@@ -110,36 +128,26 @@ ...@@ -110,36 +128,26 @@
删除 删除
</el-button> </el-button>
</ElFormItem> </ElFormItem>
<ElFormItem>
<el-button type="success" @click="handleExport">
导出
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="warning" @click="auditOrder('audit')">
审核
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'"> <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="success" @click="auditOrder('submitAudit')"> <el-button type="success" @click="auditOrder('submitAudit')">
提交审核 提交审核
</el-button> </el-button>
</ElFormItem> </ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="danger" @click="auditOrder('invalid')">
作废
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'COMPLETED'">
<el-button type="success" @click="auditOrder('archiving')">
归档
</el-button>
</ElFormItem>
<ElFormItem> <ElFormItem>
<el-button type="primary" @click="printProductTag"> <el-button type="primary" @click="printProductTag">
打印库存SKU标签 打印库存SKU标签
</el-button> </el-button>
</ElFormItem> </ElFormItem>
<ElFormItem>
<el-button
v-if="nodeCode === 'COMPLETED'"
type="success"
@click="auditOrder('archiving')"
>
归档
</el-button>
</ElFormItem>
</ElForm> </ElForm>
</div> </div>
<div <div
...@@ -162,7 +170,7 @@ ...@@ -162,7 +170,7 @@
width="70" width="70"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
type="index" type="index"
label="序号" label="序号"
...@@ -170,30 +178,30 @@ ...@@ -170,30 +178,30 @@
fixed="left" fixed="left"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
label="出库单号" label="备货单号"
show-overflow-tooltip show-overflow-tooltip
prop="outNo" prop="inNo"
width="130" width="130"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
label="单据状态" label="单据状态"
width="130" width="100"
prop="billStatusTxt" prop="billStatusTxt"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
label="仓库名称" label="备货仓库"
show-overflow-tooltip show-overflow-tooltip
prop="warehouseName" prop="warehouseName"
width="130" width="130"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
label="工厂编号" label="工厂编号"
show-overflow-tooltip show-overflow-tooltip
...@@ -201,7 +209,15 @@ ...@@ -201,7 +209,15 @@
width="90" width="90"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn
label="物流单号"
show-overflow-tooltip
prop="shipmentNumber"
width="200"
header-align="center"
align="center"
/>
<ElTableColumn <ElTableColumn
label="币种" label="币种"
show-overflow-tooltip show-overflow-tooltip
...@@ -209,7 +225,7 @@ ...@@ -209,7 +225,7 @@
prop="currencyName" prop="currencyName"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
label="总金额" label="总金额"
show-overflow-tooltip show-overflow-tooltip
...@@ -217,7 +233,23 @@ ...@@ -217,7 +233,23 @@
prop="totalPrice" prop="totalPrice"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn
label="箱数"
header-align="center"
prop="boxSum"
width="90"
align="center"
show-overflow-tooltip
/>
<ElTableColumn
label="盘点箱数"
header-align="center"
prop="checkBoxSum"
width="90"
align="center"
show-overflow-tooltip
/>
<ElTableColumn <ElTableColumn
label="SKU数量" label="SKU数量"
header-align="center" header-align="center"
...@@ -225,42 +257,83 @@ ...@@ -225,42 +257,83 @@
width="90" width="90"
align="center" align="center"
show-overflow-tooltip show-overflow-tooltip
> />
</ElTableColumn>
<ElTableColumn <ElTableColumn
label="总数量" label="备货总数量"
header-align="center" header-align="center"
prop="total" prop="total"
width="90" width="90"
align="center" align="center"
show-overflow-tooltip show-overflow-tooltip
> />
</ElTableColumn> <ElTableColumn
label="创建时间"
header-align="center"
prop="makeTime"
width="130"
align="center"
show-overflow-tooltip
/>
<ElTableColumn
label="审核时间"
header-align="center"
prop="auditTime"
width="130"
align="center"
show-overflow-tooltip
/>
<ElTableColumn
label="发货时间"
header-align="center"
prop="shipmentTime"
width="130"
align="center"
show-overflow-tooltip
/>
<ElTableColumn
label="入库时间"
header-align="center"
prop="deliveryTime"
width="130"
align="center"
show-overflow-tooltip
/>
<ElTableColumn <ElTableColumn
label="驳回原因" label="驳回原因"
show-overflow-tooltip show-overflow-tooltip
prop="rejectReason" prop="rejectReason"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
label="备注" label="备注"
show-overflow-tooltip show-overflow-tooltip
prop="remark" prop="remark"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
v-if="nodeCode === 'PENDING_SUBMIT'"
width="100" width="100"
align="center" align="center"
header-align="center" header-align="center"
label="操作" label="操作"
fixed="right"
> >
<template #default="{ row }"> <template #default="{ row }">
<ElButton type="primary" link @click="addDialog(2, row)" <ElButton
v-if="nodeCode === 'PENDING_SUBMIT'"
type="primary"
link
@click="addDialog(2, row)"
>编辑 >编辑
</ElButton> </ElButton>
<ElButton
v-if="nodeCode === 'PENDING_AUDIT'"
type="warning"
link
@click="addDialog(3, row)"
>审核
</ElButton>
</template> </template>
</ElTableColumn> </ElTableColumn>
</ElTable> </ElTable>
...@@ -280,7 +353,7 @@ ...@@ -280,7 +353,7 @@
</template> </template>
<template #bottom> <template #bottom>
<el-tabs v-model="tabsValue" @tab-click="tabsClick"> <el-tabs v-model="tabsValue" @tab-click="tabsClick">
<el-tab-pane name="0" label="库商品"> <el-tab-pane name="0" label="库商品">
<div class="table-wrap"> <div class="table-wrap">
<ElTable size="small" :data="detailList" height="100%" border> <ElTable size="small" :data="detailList" height="100%" border>
<ElTableColumn <ElTableColumn
...@@ -309,14 +382,14 @@ ...@@ -309,14 +382,14 @@
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="库存SKU" label="库存SKU"
prop="warehouseSku"
width="180" width="180"
prop="warehouseSku"
/> />
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="库存SKU" label="商品名称"
prop="skuName" prop="skuName"
/> />
<ElTableColumn <ElTableColumn
...@@ -328,8 +401,9 @@ ...@@ -328,8 +401,9 @@
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="出库数量" width="90"
prop="outCount" label="备货数量"
prop="stockUpStored"
/> />
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
...@@ -411,7 +485,7 @@ ...@@ -411,7 +485,7 @@
</div> </div>
<ElDialog <ElDialog
v-model="importDialogVisible" v-model="importDialogVisible"
title="导入库单" title="导入库单"
width="500px" width="500px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
...@@ -420,8 +494,8 @@ ...@@ -420,8 +494,8 @@
<UploadExcel <UploadExcel
v-model="importedFileUrl" v-model="importedFileUrl"
:import-type="'localAndXlsx'" :import-type="'localAndXlsx'"
:import-name="'库单'" :import-name="'库单'"
:import-url="'/files/outboundOrder.xlsx'" :import-url="'/files/warehousingEntry.xlsx'"
@imported="handleLocalImport" @imported="handleLocalImport"
/> />
</div> </div>
...@@ -429,7 +503,7 @@ ...@@ -429,7 +503,7 @@
</ElDialog> </ElDialog>
<ElDialog <ElDialog
v-model="newDialogVisible" v-model="newDialogVisible"
:title="formId ? '编辑' : '新增'" :title="actionMap[currentAction - 1].label + '备货计划'"
width="80%" width="80%"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
...@@ -441,18 +515,18 @@ ...@@ -441,18 +515,18 @@
inline inline
label-width="90px" label-width="90px"
> >
<ElFormItem label="出库单号" prop="account"> <ElFormItem label="备货单号" prop="account">
<ElInput v-model.trim="editForm.outNo" clearable disabled /> <ElInput v-model.trim="editForm.inNo" clearable disabled />
</ElFormItem> </ElFormItem>
<ElFormItem label="工厂:" prop="factoryCode"> <ElFormItem label="工厂编号:" prop="factoryCode">
<span>{{ editForm.factoryCode }}</span> <span>{{ editForm.factoryCode }}</span>
</ElFormItem> </ElFormItem>
<ElFormItem label="仓库" prop="warehouseId" required> <ElFormItem label="备货仓库" prop="warehouseId" required>
<ElSelect <ElSelect
v-model="editForm.warehouseId" v-model="editForm.warehouseId"
clearable clearable
:disabled="formId" :disabled="formId"
placeholder="请选择仓库" placeholder="请选择备货仓库"
style="width: 160px" style="width: 160px"
@change="handleWarehouseChange(editForm.warehouseId)" @change="handleWarehouseChange(editForm.warehouseId)"
> >
...@@ -464,10 +538,21 @@ ...@@ -464,10 +538,21 @@
></ElOption> ></ElOption>
</ElSelect> </ElSelect>
</ElFormItem> </ElFormItem>
<ElFormItem label="备注" prop="remark" style="width: 45%"> <ElFormItem label="箱数" prop="boxSum">
<ElInput
v-model.trim="editForm.boxSum"
placeholder="请输入箱数"
:disabled="currentAction === 3"
style="width: 160px"
clearable
/>
</ElFormItem>
<ElFormItem label="备注" prop="remark">
<ElInput <ElInput
v-model.trim="editForm.remark" v-model.trim="editForm.remark"
:disabled="currentAction === 3"
placeholder="请输入备注" placeholder="请输入备注"
style="width: 160px"
clearable clearable
/> />
</ElFormItem> </ElFormItem>
...@@ -484,14 +569,14 @@ ...@@ -484,14 +569,14 @@
width="70" width="70"
header-align="center" header-align="center"
align="center" align="center"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
width="60" width="60"
align="center" align="center"
label="序号" label="序号"
type="index" type="index"
></ElTableColumn> />
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
...@@ -522,17 +607,12 @@ ...@@ -522,17 +607,12 @@
label="款号" label="款号"
prop="productNo" prop="productNo"
/> />
<ElTableColumn <ElTableColumn align="center" label="备货数量" prop="stockUpStored">
show-overflow-tooltip
align="center"
label="可用库存数量"
prop="usableInventory"
/>
<ElTableColumn align="center" label="出库数量" prop="outCount">
<template #default="{ row }"> <template #default="{ row }">
<el-input <el-input
v-model.number="row.outCount" v-model.number="row.stockUpStored"
placeholder="出库数量" :disabled="currentAction === 3"
placeholder="备货数量"
style="width: 120px" style="width: 120px"
clearable clearable
size="small" size="small"
...@@ -541,8 +621,8 @@ ...@@ -541,8 +621,8 @@
</template> </template>
</ElTableColumn> </ElTableColumn>
<ElTableColumn <ElTableColumn
width="80"
align="center" align="center"
width="80"
label="币种" label="币种"
prop="currencyName" prop="currencyName"
/> />
...@@ -560,12 +640,12 @@ ...@@ -560,12 +640,12 @@
/> />
<ElTableColumn align="center" label="库位" prop="locationCode"> <ElTableColumn align="center" label="库位" prop="locationCode">
<template #default="{ row }"> <template #default="{ row }">
<span v-if="row.locationCode">{{ row.locationCode }}</span> <!-- <span v-if="formId&&row.locationCode">{{ row.locationCode }}</span> -->
<ElSelect <ElSelect
v-else
v-model="row.locationId" v-model="row.locationId"
clearable clearable
placeholder="请输入库位" placeholder="请输入库位"
:disabled="currentAction === 3"
style="width: 120px" style="width: 120px"
filterable filterable
@change="handleLocationChange(row.locationId, row)" @change="handleLocationChange(row.locationId, row)"
...@@ -587,14 +667,19 @@ ...@@ -587,14 +667,19 @@
prop="remark" prop="remark"
> >
<template #default="{ row }"> <template #default="{ row }">
<ElInput v-model.trim="row.remark" clearable size="small" /> <ElInput
v-model.trim="row.remark"
clearable
size="small"
:disabled="currentAction === 3"
/>
</template> </template>
</ElTableColumn> </ElTableColumn>
</ElTable> </ElTable>
</div> </div>
<template #footer> <template #footer>
<div class="product-dialog-footer"> <div class="product-dialog-footer">
<div> <div v-if="currentAction !== 3">
<el-input <el-input
v-model.trim="selectSku" v-model.trim="selectSku"
placeholder="库存SKU" placeholder="库存SKU"
...@@ -604,7 +689,7 @@ ...@@ -604,7 +689,7 @@
></el-input> ></el-input>
<el-popover placement="top-start" width="1000" trigger="click"> <el-popover placement="top-start" width="1000" trigger="click">
<div v-if="skuData.length > 0" style="height: 50vh"> <div v-if="skuData.length > 0" style="height: 50vh">
<ElTable size="small" :data="skuData" height="100%" border> <ElTable size="small" :data="filterSkuData" height="100%" border>
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
width="60" width="60"
...@@ -636,7 +721,7 @@ ...@@ -636,7 +721,7 @@
align="center" align="center"
width="200" width="200"
label="库存SKU" label="库存SKU"
prop="warehouseSku" prop="sku"
/> />
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
...@@ -656,7 +741,7 @@ ...@@ -656,7 +741,7 @@
align="center" align="center"
label="成本价" label="成本价"
width="80" width="80"
prop="price" prop="factoryPrice"
/> />
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
...@@ -671,9 +756,9 @@ ...@@ -671,9 +756,9 @@
label="操作" label="操作"
> >
<template #default="{ row }"> <template #default="{ row }">
<el-icon :size="32" color="#67C23A" class="cursor-pointer" <el-icon :size="32" color="#67C23A" class="cursor-pointer">
><CirclePlusFilled @click="skudblclick(row)" <CirclePlusFilled @click="skudblclick(row)" />
/></el-icon> </el-icon>
</template> </template>
</ElTableColumn> </ElTableColumn>
</ElTable> </ElTable>
...@@ -714,15 +799,23 @@ ...@@ -714,15 +799,23 @@
导入 导入
</el-button> </el-button>
</div> </div>
<div> <div :style="{ margin: currentAction === 3 ? '0 auto' : '' }">
<el-button size="small" @click="newDialogVisible = false">
取消
</el-button>
<el-button <el-button
v-if="currentAction === 3"
type="danger"
size="small" size="small"
style="margin-left: 10px" @click="rejectInAudit"
@click="newDialogVisible = false"
> >
取消 驳回
</el-button> </el-button>
<el-button type="primary" size="small" @click="addOtherCurrency()"> <el-button
type="primary"
size="small"
@click="currentAction === 2 ? addOtherCurrency : handleOudit"
>
保存 保存
</el-button> </el-button>
</div> </div>
...@@ -744,7 +837,7 @@ ...@@ -744,7 +837,7 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label=""> <el-form-item label="">
<el-checkbox v-model="exportForm.delivery"> 包含详情 </el-checkbox> <el-checkbox v-model="exportForm.delivery"> 包含详情</el-checkbox>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
...@@ -836,42 +929,43 @@ import usePageList from '@/utils/hooks/usePageList' ...@@ -836,42 +929,43 @@ import usePageList from '@/utils/hooks/usePageList'
import { checkUpdateParams, AnyObject } from '@/utils/hooks/commonUtil' import { checkUpdateParams, AnyObject } from '@/utils/hooks/commonUtil'
import { useValue } from '@/utils/hooks/useValue' import { useValue } from '@/utils/hooks/useValue'
import { import {
getOutRecordStatusTree, getStackingPlanStatusTree,
warehouseOutRecordListPage, getStackingPlanListPage,
getWarehouseOutRecordDetailApi, getStackingPlanDetailApi,
getItemListByIdApi, getBySkuApi,
getBySkuAndWarehouseIdApi,
warehouseInfoGetAll, warehouseInfoGetAll,
getByWareHouseIdAndCodeApi, getByWareHouseIdAndCodeApi,
addOutRecordApi, addStackingPlanApi,
updateOutRecordApi, updateStackingPlanApi,
deleteWarehouseOutRecordApi, deleteStackingPlanApi,
auditOrderApi, auditOrderApi,
getOutRecordLogApi, getStackingPlanLogApi,
rejectOutRecordApi, rejectStackingPlanApi,
LogListData, LogListData,
warehouseInfo, warehouseInfo,
warehouseOutRecordExport, InRecordBatchCheckPrintApi,
factoryWarehouseInventoryPrint, factoryWarehouseInventoryPrint,
OutRecordBatchCheckPrintApi, warehouseInRecordExport,
auditStackingPlanApi,
} from '@/api/warehouse' } from '@/api/warehouse'
import { filePath } from '@/api/axios' import { filePath } from '@/api/axios.ts'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
import { ref, onMounted, watch, nextTick } from 'vue' import { ref, onMounted, watch, nextTick } from 'vue'
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
import { import {
warehouseSearchForm, stockingPlanSearchForm,
InterWarehousePage, InterWarehousePage,
InterWarehouseTree, InterWarehouseTree,
InterProductList, InterProductList,
InterskuList, InterskuList,
ILocation, ILocation,
InterWarehouseDetail, InterStackingPlanDetail,
} from '@/types/api/warehouse' } from '@/types/api/warehouse'
import ImageView from '@/components/ImageView.vue' import ImageView from '@/components/ImageView.vue'
import { useEnterKeyTrigger } from '@/utils/hooks/useEnterKeyTrigger.ts'
import UploadExcel from '@/components/UploadExcel.vue' import UploadExcel from '@/components/UploadExcel.vue'
// import { debounce } from 'lodash-es' // import { debounce } from 'lodash-es'
import { useEnterKeyTrigger } from '@/utils/hooks/useEnterKeyTrigger.ts'
const warehouseList = ref<warehouseInfo[]>([]) const warehouseList = ref<warehouseInfo[]>([])
const pickerOptions = { const pickerOptions = {
shortcuts: [ shortcuts: [
...@@ -983,6 +1077,7 @@ const pickerOptions = { ...@@ -983,6 +1077,7 @@ const pickerOptions = {
}, },
], ],
} }
function getStartTime() { function getStartTime() {
const date = new Date() const date = new Date()
const year = date.getFullYear() const year = date.getFullYear()
...@@ -992,7 +1087,7 @@ function getStartTime() { ...@@ -992,7 +1087,7 @@ function getStartTime() {
} }
const selectSku = ref('') const selectSku = ref('')
const treeData = ref<InterWarehouseTree[]>() const treeData = ref<InterWarehouseTree[]>()
const [searchForm, resetSearchForm] = useValue<warehouseSearchForm>({}) const [searchForm, resetSearchForm] = useValue<stockingPlanSearchForm>({})
const tradingTime = ref<string[]>([]) const tradingTime = ref<string[]>([])
const selections = ref<InterWarehousePage[]>([]) const selections = ref<InterWarehousePage[]>([])
...@@ -1024,12 +1119,12 @@ const { ...@@ -1024,12 +1119,12 @@ const {
onPageSizeChange: handleSizeChange, onPageSizeChange: handleSizeChange,
} = usePageList({ } = usePageList({
query: (page, pageSize) => query: (page, pageSize) =>
warehouseOutRecordListPage( getStackingPlanListPage(
{ {
...searchForm.value, ...searchForm.value,
billStatus: nodeCode.value == 'all' ? 'all' : nodeCode.value, billStatus: nodeCode.value == 'all' ? 'all' : nodeCode.value,
startTime: tradingTime.value && tradingTime.value[0], startDate: tradingTime.value && tradingTime.value[0],
endTime: tradingTime.value && tradingTime.value[1], endDate: tradingTime.value && tradingTime.value[1],
}, },
page, page,
pageSize, pageSize,
...@@ -1042,15 +1137,15 @@ const setCostPrice = (item: InterProductList) => { ...@@ -1042,15 +1137,15 @@ const setCostPrice = (item: InterProductList) => {
return return
} }
if (item) { if (item) {
const outCount = item.outCount ?? 0 const buyStored = item.buyStored ?? 0
const costPrice = item.costPrice ?? 0 const costPrice = item.costPrice ?? 0
const amount = new BigNumber(outCount).multipliedBy(costPrice).toFixed(2) const amount = new BigNumber(buyStored).multipliedBy(costPrice).toFixed(2)
item.totalPrice = Number(amount) item.totalPrice = Number(amount)
} }
} }
const getTreeNum = async () => { const getTreeNum = async () => {
try { try {
const res = await getOutRecordStatusTree() const res = await getStackingPlanStatusTree()
res.data = [{ code: 'all', name: '全部', children: res.data }] res.data = [{ code: 'all', name: '全部', children: res.data }]
treeData.value = res.data treeData.value = res.data
await nextTick(() => { await nextTick(() => {
...@@ -1068,7 +1163,7 @@ const printProductTag = async () => { ...@@ -1068,7 +1163,7 @@ const printProductTag = async () => {
} }
const str = selections.value.map((el: InterWarehousePage) => el.id).join(',') const str = selections.value.map((el: InterWarehousePage) => el.id).join(',')
try { try {
const res = await OutRecordBatchCheckPrintApi(str) const res = await InRecordBatchCheckPrintApi(str)
if (res.code === 200) { if (res.code === 200) {
printData.value = res.data printData.value = res.data
showPrintDialog.value = true showPrintDialog.value = true
...@@ -1079,6 +1174,7 @@ const printProductTag = async () => { ...@@ -1079,6 +1174,7 @@ const printProductTag = async () => {
console.error(e) console.error(e)
} }
} }
async function handlePrintProductTag() { async function handlePrintProductTag() {
const flag = printData.value.every( const flag = printData.value.every(
(el: InterWarehousePage) => el.number && el.number != '0', (el: InterWarehousePage) => el.number && el.number != '0',
...@@ -1108,13 +1204,14 @@ async function handlePrintProductTag() { ...@@ -1108,13 +1204,14 @@ async function handlePrintProductTag() {
showPrintDialog.value = false showPrintDialog.value = false
window.open(filePath + res.message, '_blank') window.open(filePath + res.message, '_blank')
} }
const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => { const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => {
if (!editForm.value.warehouseId) { if (!editForm.value.warehouseId) {
ElMessage.error('请选择仓库') ElMessage.error('请选择仓库')
return [] return []
} }
try { try {
const res = await getBySkuAndWarehouseIdApi(editForm.value.warehouseId, sku) const res = await getBySkuApi(editForm.value.warehouseId, sku)
const arr: InterskuList[] = res.data || [] const arr: InterskuList[] = res.data || []
const ids: Record<string, boolean> = {} const ids: Record<string, boolean> = {}
// 过滤掉商品列表已经加了的 // 过滤掉商品列表已经加了的
...@@ -1125,9 +1222,7 @@ const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => { ...@@ -1125,9 +1222,7 @@ const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => {
} }
// 使用 filter 方法过滤掉已经存在的 SKU // 使用 filter 方法过滤掉已经存在的 SKU
const filteredArr = arr.filter((currentItem: InterskuList) => { const filteredArr = arr.filter((currentItem: InterskuList) => {
return ( return currentItem.sku === undefined || !ids[currentItem.sku]
currentItem.warehouseSku === undefined || !ids[currentItem.warehouseSku]
)
}) })
return filteredArr return filteredArr
} catch (e) { } catch (e) {
...@@ -1135,30 +1230,32 @@ const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => { ...@@ -1135,30 +1230,32 @@ const batchAddCommodity = async (sku: string): Promise<InterskuList[]> => {
return [] return []
} }
} }
interface InterImportData { interface InterImportData {
warehouseSku: string warehouseSku: string
remark?: string | null remark?: string | null
outCount?: string | number | null | object // 扩大 outCount 类型,以兼容原始数据
[propName: string]: string | number | boolean | undefined | unknown [key: string]: unknown
} }
// 前端导入Excel // 前端导入Excel
const excelFieldMap: Record<string, keyof InterImportData> = { const excelFieldMap: Record<string, keyof InterProductList> = {
// SKU图片: 'skuImage', // SKU图片: 'skuImage',
库存SKU: 'warehouseSku', 库存SKU: 'warehouseSku',
// SKU名称: 'skuName', // SKU名称: 'skuName',
出库数量: 'outCount', 备货数量: 'stockUpStored',
// 可用库存数量: 'usableInventory',
// '成本价(¥)': 'costPrice', // '成本价(¥)': 'costPrice',
// '总成本(¥)': 'totalPrice', // '总成本(¥)': 'totalPrice',
// 库位: 'locationCode', 库位编码: 'locationCode',
备注: 'remark', 备注: 'remark',
} }
const handleLocalImport = async ({ const handleLocalImport = async ({
path, path,
data, data,
}: { }: {
path: string path: string
data: Record<string, unknown>[] data: InterImportData[]
}) => { }) => {
// 1. 将原始导入数据映射到 InterImportData[] // 1. 将原始导入数据映射到 InterImportData[]
const importedData: InterImportData[] = data const importedData: InterImportData[] = data
...@@ -1177,15 +1274,15 @@ const handleLocalImport = async ({ ...@@ -1177,15 +1274,15 @@ const handleLocalImport = async ({
: value === null || value === undefined : value === null || value === undefined
? null ? null
: String(value) : String(value)
} else if (field === 'outCount') { } else if (field === 'buyStored') {
// 处理 outCount: 确保它是一个数字、数字字符串,否则设置为 null // 确保 value 是一个有效的数字或数字字符串,否则设置为 null
if (typeof value === 'number') { if (
obj[field] = String(value) // 将数字转换为字符串 typeof value === 'number' ||
} else if (typeof value === 'string' && !isNaN(Number(value))) { (typeof value === 'string' && !isNaN(Number(value)))
obj[field] = value // 保持有效的数字字符串 ) {
obj[field] = String(value) // 转换为字符串
} else { } else {
// 如果不是数字或有效的数字字符串,则设置为 null obj[field] = null // 无效值设置为 null
obj[field] = null
} }
} else { } else {
obj[field] = value obj[field] = value
...@@ -1194,77 +1291,51 @@ const handleLocalImport = async ({ ...@@ -1194,77 +1291,51 @@ const handleLocalImport = async ({
return obj return obj
}) })
.filter((item) => item.warehouseSku) .filter((item) => item.warehouseSku)
// console.log('@', importedData, data)
if (importedData.length === 0) { if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的库存SKU') ElMessage.warning('导入数据中没有有效的商品SKU')
importDialogVisible.value = false importDialogVisible.value = false
return return
} }
// 2. 提取导入的 SKU 列表 // 2. 提取导入的 SKU 列表
const importedSkus = importedData.map((item) => item.warehouseSku).join(',') const importedSkus = importedData.map((item) => item.warehouseSku).join(',')
// 3. 调用 batchAddCommodity 获取商品的完整信息并过滤掉已有的 SKU // 3. 调用 batchAddCommodity 获取商品的完整信息并过滤掉已有的 SKU
const filteredSkusList = await batchAddCommodity(importedSkus) const filteredSkusList = await batchAddCommodity(importedSkus) // 使用 await 等待结果
if (filteredSkusList.length === 0) { if (filteredSkusList.length === 0) {
ElMessage.warning('导入的库存SKU已存在或无效') ElMessage.warning('导入的商品SKU已存在或无效')
importedFileUrl.value = path importedFileUrl.value = path
importDialogVisible.value = false importDialogVisible.value = false
return return
} }
// 4. 将备注信息合并到获取到的商品列表中 // 4. 将备注信息合并到获取到的商品列表中
const mergedProductList = filteredSkusList.map((skuItem) => { const mergedProductList = filteredSkusList.map((skuItem) => {
// 在导入数据中找到匹配的备注信息
const importedItem = importedData.find( const importedItem = importedData.find(
(item) => item.warehouseSku === skuItem.warehouseSku, (item) => item.warehouseSku === skuItem.sku,
) )
const target = locationList.value.find((item: InterProductList) => {
let outCountValueForBigNumber: string | number = '0' // 初始化为安全默认值 return item.locationCode == importedItem?.locationCode
console.log(importedItem) })
if (
importedItem?.outCount !== null &&
importedItem?.outCount !== undefined
) {
if (
typeof importedItem.outCount === 'string' &&
!isNaN(Number(importedItem.outCount))
) {
outCountValueForBigNumber = importedItem.outCount
} else if (typeof importedItem.outCount === 'number') {
outCountValueForBigNumber = importedItem.outCount
} else {
// 如果是对象或其他意外类型,则默认为 '0'
outCountValueForBigNumber = '0'
}
}
const calculatedOutCount = new BigNumber(
outCountValueForBigNumber,
).toNumber()
return { return {
skuImage: skuItem.image, skuImage: skuItem.image,
warehouseSku: skuItem.warehouseSku, warehouseSku: skuItem.sku,
skuName: skuItem.skuName, skuName: skuItem.skuName,
productNo: skuItem.productNumber, productNo: skuItem.productNo,
locationCode: skuItem.locationCode ?? '', locationCode: target?.locationCode ?? '',
locationId: skuItem.locationId ?? null, locationId: target?.locationId,
costPrice: skuItem.price, costPrice: skuItem.factoryPrice,
outCount: calculatedOutCount, buyStored: importedItem?.buyStored ?? null,
totalPrice: new BigNumber(calculatedOutCount) totalPrice: new BigNumber(
.multipliedBy(skuItem.price ?? 0) (importedItem?.buyStored ?? 0) as number | string,
)
.multipliedBy(skuItem.factoryPrice ?? 0)
.toNumber(), .toNumber(),
usableInventory: skuItem.usableInventory, usableInventory: skuItem.usableInventory,
inventoryId: skuItem.id, remark: importedItem?.remark ?? null,
remark: importedItem?.remark ?? skuItem.remark ?? null, } as InterProductList // 明确类型
} as InterProductList
}) })
// 5. 更新 otherPurchaseData // 5. 更新 otherPurchaseData
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList] otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
importedFileUrl.value = path importedFileUrl.value = path
importDialogVisible.value = false importDialogVisible.value = false
} }
...@@ -1280,20 +1351,20 @@ const submitExportForm = async () => { ...@@ -1280,20 +1351,20 @@ const submitExportForm = async () => {
if (exportForm.value.resource === '') { if (exportForm.value.resource === '') {
return ElMessage.error('请选择导出类型') return ElMessage.error('请选择导出类型')
} }
let purchaseIds: number[] = [] let purchaseIds = ''
let exportTotal: number | undefined = undefined let exportTotal: number | undefined = undefined
const params: AnyObject = {} const params: AnyObject = {}
const resourceType = Number(exportForm.value.resource) const resourceType = Number(exportForm.value.resource)
if (resourceType === 0) { if (resourceType === 0) {
purchaseIds = (tableData.value as InterWarehousePage[]).map( purchaseIds = tableData.value
(el: InterWarehousePage) => Number(el.id), .map((el: InterWarehousePage) => el.id)
) .join(',')
} else if (resourceType === 1) { } else if (resourceType === 1) {
purchaseIds = selections.value.map((el: InterWarehousePage) => purchaseIds = selections.value
Number(el.id), .map((el: InterWarehousePage) => el.id)
) .join(',')
} else if (resourceType === 2) { } else if (resourceType === 2) {
purchaseIds = [] purchaseIds = ''
exportTotal = total.value exportTotal = total.value
params.billStatus = nodeCode.value == 'all' ? 'all' : nodeCode.value params.billStatus = nodeCode.value == 'all' ? 'all' : nodeCode.value
} }
...@@ -1302,7 +1373,7 @@ const submitExportForm = async () => { ...@@ -1302,7 +1373,7 @@ const submitExportForm = async () => {
params.total = exportTotal params.total = exportTotal
} }
try { try {
const res = await warehouseOutRecordExport({ const res = await warehouseInRecordExport({
showDetail: exportForm.value.delivery, showDetail: exportForm.value.delivery,
...params, ...params,
...searchForm.value, ...searchForm.value,
...@@ -1335,29 +1406,8 @@ const skuData = ref<InterskuList[]>([]) ...@@ -1335,29 +1406,8 @@ const skuData = ref<InterskuList[]>([])
const selectbySku = async () => { const selectbySku = async () => {
if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库') if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库')
try { try {
const res = await getBySkuAndWarehouseIdApi( const res = await getBySkuApi(editForm.value.warehouseId, selectSku.value)
editForm.value.warehouseId, skuData.value = res.data || []
selectSku.value,
)
const arr: InterskuList[] = res.data || []
const ids: Record<string, boolean> = {}
// 过滤掉商品列表已经加了的
for (const item of otherPurchaseData.value) {
if (item.warehouseSku !== undefined) {
ids[item.warehouseSku] = true
}
}
for (let i = 0; i < arr.length; i++) {
const currentItem: InterskuList = arr[i]
if (
currentItem.warehouseSku !== undefined &&
ids[currentItem.warehouseSku]
) {
arr.splice(i, 1)
i--
}
}
skuData.value = arr || []
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
...@@ -1366,16 +1416,14 @@ const skudblclick = (val: InterskuList) => { ...@@ -1366,16 +1416,14 @@ const skudblclick = (val: InterskuList) => {
// 使用可选链和空值合并运算符处理可能的null值 // 使用可选链和空值合并运算符处理可能的null值
const { const {
locationCode = '', locationCode = '',
price = null, factoryPrice = null,
productNo = '', productNo = '',
warehouseSku = '', sku = '',
skuName = '', skuName = '',
image = '', image = '',
locationId = null, locationId = null,
usableInventory = null,
id = null,
currencyName = '', currencyName = '',
currencyCode = '', currencyCode = null,
} = val || {} } = val || {}
// 币种一致性校验 // 币种一致性校验
...@@ -1387,31 +1435,29 @@ const skudblclick = (val: InterskuList) => { ...@@ -1387,31 +1435,29 @@ const skudblclick = (val: InterskuList) => {
return return
} }
} }
otherPurchaseData.value = [ otherPurchaseData.value = [
...otherPurchaseData.value, ...otherPurchaseData.value,
{ {
skuImage: image, skuImage: image,
warehouseSku, warehouseSku: sku,
skuName, skuName,
productNo, productNo,
locationCode: locationCode ?? '', // 确保空值处理 locationCode: locationCode ?? '', // 确保空值处理
locationId: locationId ?? null, // 确保空值处理 locationId: locationId ?? null, // 确保空值处理
costPrice: price, costPrice: factoryPrice,
outCount: null, //出库数量 buyStored: null,
totalPrice: null, totalPrice: null,
usableInventory, //可用库存数量
inventoryId: id,
currencyName, currencyName,
currencyCode, currencyCode,
}, },
] ]
// 使用filter代替forEach+splice,时间复杂度从O(n^2)降到O(n) // 使用filter代替forEach+splice,时间复杂度从O(n^2)降到O(n)
const skuSet = new Set( const skuSet = new Set(
otherPurchaseData.value.map((item: InterProductList) => item.warehouseSku), otherPurchaseData.value.map((item: InterProductList) => item.warehouseSku),
) )
skuData.value = skuData.value.filter( skuData.value = skuData.value.filter(
(item: InterskuList) => !skuSet.has(item.warehouseSku), (item: InterskuList) => !skuSet.has(item.sku),
) )
} }
const tabsClick = async () => { const tabsClick = async () => {
...@@ -1427,8 +1473,8 @@ const tabsClick = async () => { ...@@ -1427,8 +1473,8 @@ const tabsClick = async () => {
getLogList() getLogList()
} }
} }
const [editForm, resetEditForm] = useValue<InterWarehouseDetail>({ const [editForm, resetEditForm] = useValue<InterStackingPlanDetail>({
outNo: '', inNo: '',
warehouseId: '', warehouseId: '',
warehouseName: '', warehouseName: '',
remark: '', remark: '',
...@@ -1440,9 +1486,16 @@ const newDialogVisible = ref(false) ...@@ -1440,9 +1486,16 @@ const newDialogVisible = ref(false)
const editFormRef = ref() const editFormRef = ref()
const editForm2 = ref({}) const editForm2 = ref({})
const formId = ref<number | undefined>(undefined) const formId = ref<number | undefined>(undefined)
const actionMap = [
{ label: '新增', value: 1 },
{ label: '编辑', value: 2 },
{ label: '审核', value: 3 },
]
const currentAction = ref<number>(1)
const otherPurchaseData = ref<InterProductList[]>([]) const otherPurchaseData = ref<InterProductList[]>([])
const addDialog = async (i: number, v: InterWarehousePage | null) => { const addDialog = async (i: number, v: InterWarehousePage | null) => {
if (i === 2) { currentAction.value = i
if (i === 2 || i === 3) {
if (v) formId.value = v.id if (v) formId.value = v.id
if (v) getProduct(v.id) if (v) getProduct(v.id)
if (!formId.value) return ElMessage('请勾选至少一条记录') if (!formId.value) return ElMessage('请勾选至少一条记录')
...@@ -1477,22 +1530,9 @@ const addDialog = async (i: number, v: InterWarehousePage | null) => { ...@@ -1477,22 +1530,9 @@ const addDialog = async (i: number, v: InterWarehousePage | null) => {
} }
const getProduct = async (id: number | undefined) => { const getProduct = async (id: number | undefined) => {
try { try {
const res = await getWarehouseOutRecordDetailApi(id) const res = await getStackingPlanDetailApi(id)
const productList = res.data?.productList
const newProductList = (Array.isArray(productList) ? productList : []).map(
(item: InterProductList) => {
const { inventory, ...rest } = item
return {
...rest,
usableInventory: inventory?.usableInventory ?? null,
}
},
)
if (res.data) {
res.data.productList = newProductList
}
editForm.value = JSON.parse(JSON.stringify(res.data)) editForm.value = JSON.parse(JSON.stringify(res.data))
otherPurchaseData.value = newProductList || [] otherPurchaseData.value = res.data?.productList || []
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
...@@ -1511,27 +1551,16 @@ const auditOrder = (key: string) => { ...@@ -1511,27 +1551,16 @@ const auditOrder = (key: string) => {
let url = '' let url = ''
let text = '' let text = ''
switch (key) { switch (key) {
case 'invalid':
url = 'factory/warehouseOutRecord/invalid'
text = '作废'
break
case 'archiving': case 'archiving':
url = 'factory/warehouseOutRecord/archive' url = 'factory/warehouseInRecord/archive'
text = '归档' text = '归档'
break break
case 'submitAudit': case 'submitAudit':
url = 'factory/warehouseOutRecord/submitAudit' url = 'factoryStockingPlanRecord/submit_audit'
text = '提交审核' text = '提交审核'
break break
case 'audit':
url = 'factory/warehouseOutRecord/audit'
text = '审核'
break
} }
const confimText = const confimText = `确定对选中的信息进行${text}?`
key === 'audit'
? '确定进行审核?点"确定"将会直接更改库存数量,请在审核前确认数量是否正确。'
: `确定对选中的信息进行${text}?`
ElMessageBox.confirm(confimText, '重要提示', { ElMessageBox.confirm(confimText, '重要提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
type: 'warning', type: 'warning',
...@@ -1548,6 +1577,43 @@ const auditOrder = (key: string) => { ...@@ -1548,6 +1577,43 @@ const auditOrder = (key: string) => {
await getTreeNum() await getTreeNum()
}) })
} }
const handleOudit = async () => {
await auditStackingPlanApi({
id: currentRow.value?.id,
dataVersion: currentRow.value?.dataVersion,
})
ElMessage.success('操作成功')
search()
await getTreeNum()
}
const rejectInAudit = () => {
ElMessageBox.prompt('请输入驳回原因', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
inputPattern: /.+/,
customClass: 'reject',
inputErrorMessage: '请输入驳回原因',
inputPlaceholder: '驳回原因',
}).then(async ({ value }: { value: string }) => {
const data = [currentRow.value as InterProductList]
try {
await rejectStackingPlanApi({
list: data,
rejectReason: value,
status: nodeCode.value,
})
ElMessage.success('操作成功')
newDialogVisible.value = false
search()
await getTreeNum()
} catch (e) {
console.error(e)
}
})
}
const rejectedInRecord = () => { const rejectedInRecord = () => {
if (selections.value.length === 0) { if (selections.value.length === 0) {
return ElMessage.warning('请选择要操作的数据') return ElMessage.warning('请选择要操作的数据')
...@@ -1568,7 +1634,11 @@ const rejectedInRecord = () => { ...@@ -1568,7 +1634,11 @@ const rejectedInRecord = () => {
}), }),
) )
try { try {
await rejectOutRecordApi({ list: data, rejectReason: value }) await rejectStackingPlanApi({
list: data,
rejectReason: value,
status: nodeCode.value,
})
ElMessage.success('操作成功') ElMessage.success('操作成功')
search() search()
await getTreeNum() await getTreeNum()
...@@ -1591,7 +1661,6 @@ watch( ...@@ -1591,7 +1661,6 @@ watch(
}, },
{ immediate: true }, { immediate: true },
) )
watch( watch(
() => editForm.value.warehouseId, () => editForm.value.warehouseId,
(newVal: number | string | undefined) => { (newVal: number | string | undefined) => {
...@@ -1611,57 +1680,42 @@ const addOtherCurrency = async () => { ...@@ -1611,57 +1680,42 @@ const addOtherCurrency = async () => {
ElMessage.error('请至少选择一条数据') ElMessage.error('请至少选择一条数据')
return return
} }
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
if (!arr[i].outCount) { if (!arr[i].stockUpStored) {
ElMessage.error('请输入出库数量') ElMessage.error('请输入备货数量')
return
}
const usableInventory = arr[i].usableInventory || 0
if ((arr[i].outCount as number) > usableInventory) {
ElMessage.error('出库数量不能大于可用库存数量')
return return
} }
if (!arr[i].locationId) { if (!arr[i].locationId) {
ElMessage.error('请选择库位') ElMessage.error('请选择库位')
return return
} }
const found = locationList.value.find(
(item: InterProductList) => item.locationId === arr[i].locationId,
)
if (!arr[i].locationCode) {
arr[i].locationCode = found ? found?.locationCode : ''
}
} }
// 看新增后要不要打印标签
// try {
// if (!editId.value) {
// await addUserApi({
// ...editForm.value,
// supperMark: Number(editForm.value.supperMark),
// status: Number(editForm.value.status),
// })
// } else {
// await updateUserApi({
// ...editForm.value,
// supperMark: Number(editForm.value.supperMark),
// status: Number(editForm.value.status),
// })
// }
// ElMessage({
// message: '保存成功',
// type: 'success',
// offset: window.innerHeight / 2,
// })
// newDialogVisible.value = false
// search()
// } catch (e) {
// return
// }
if (!formId.value) { if (!formId.value) {
addSection() addSection()
} else { } else {
upSection() upSection()
} }
} }
const filterSkuData = computed(() => {
const skuList = otherPurchaseData.value.map((el) => el.warehouseSku)
// console.log(skuList, skuData.value)
return skuData.value.filter((el) => !skuList.includes(el.sku))
})
const addSection = async () => { const addSection = async () => {
const params = { ...editForm.value } const params = { ...editForm.value }
params.productList = otherPurchaseData.value
try { try {
await addOutRecordApi(params) await addStackingPlanApi({
...params,
productList: otherPurchaseData.value,
})
ElMessage.success('保存成功') ElMessage.success('保存成功')
newDialogVisible.value = false newDialogVisible.value = false
search() search()
...@@ -1669,45 +1723,21 @@ const addSection = async () => { ...@@ -1669,45 +1723,21 @@ const addSection = async () => {
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
// post(url, params).then((res: any) => {
// if (res.code === 200) {
// otherDialogVisible.value = false;
// ElConfirm('保存成功,是否打印标签?', '提示', {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
// type: 'warning',
// })
// .then(() => {
// if (res.message) {
// getPrintData(res.message, true);
// } else {
// ElMessage.warning('入口单号为空,无法打印');
// }
// })
// .catch((e: any) => {
// console.error(e);
// });
// getList();
// getStatusAmount();
// } else {
// ElAlert(res.message, '错误提示', {
// dangerouslyUseHTMLString: true,
// });
// }
// });
} }
const upSection = async () => { const upSection = async () => {
const params = { ...editForm.value } const params = { ...editForm.value }
// params.productList = otherPurchaseData.value
const result = checkUpdateParams( const result = checkUpdateParams(
{ ...params, productList: otherPurchaseData.value }, { ...params, productList: otherPurchaseData.value },
editForm.value as unknown as AnyObject, editForm.value as unknown as AnyObject,
'id', 'id',
{ {
productList: 'id', productList: 'warehouseSku',
}, },
) )
try { try {
await updateOutRecordApi(result) await updateStackingPlanApi(result as InterStackingPlanDetail)
newDialogVisible.value = false newDialogVisible.value = false
ElMessage.success('修改成功') ElMessage.success('修改成功')
search() search()
...@@ -1717,9 +1747,10 @@ const upSection = async () => { ...@@ -1717,9 +1747,10 @@ const upSection = async () => {
} }
} }
const addPurchaseVisible = ref(false) const addPurchaseVisible = ref(false)
const purchaseTextarea = ref(null) const purchaseTextarea = ref('')
const addPurchase = async () => { const addPurchase = async () => {
addPurchaseVisible.value = true addPurchaseVisible.value = true
purchaseTextarea.value = ''
} }
const submitPurchase = async () => { const submitPurchase = async () => {
if (!purchaseTextarea.value) { if (!purchaseTextarea.value) {
...@@ -1730,16 +1761,15 @@ const submitPurchase = async () => { ...@@ -1730,16 +1761,15 @@ const submitPurchase = async () => {
const mergedProductList = filteredSkusList.map((skuItem) => { const mergedProductList = filteredSkusList.map((skuItem) => {
return { return {
skuImage: skuItem.image, skuImage: skuItem.image,
warehouseSku: skuItem.warehouseSku, warehouseSku: skuItem.sku,
skuName: skuItem.skuName, skuName: skuItem.skuName,
productNo: skuItem.productNumber, productNo: skuItem.productNo,
locationCode: skuItem.locationCode ?? '', locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null, locationId: skuItem.locationId ?? null,
costPrice: skuItem.price, costPrice: skuItem.factoryPrice,
outCount: null, stockUpStored: null,
totalPrice: null, totalPrice: null,
usableInventory: skuItem.usableInventory, usableInventory: skuItem.usableInventory,
inventoryId: skuItem.id,
remark: null, remark: null,
} as InterProductList } as InterProductList
}) })
...@@ -1770,7 +1800,7 @@ const handleBatchDelete = async () => { ...@@ -1770,7 +1800,7 @@ const handleBatchDelete = async () => {
type: 'warning', type: 'warning',
}) })
const str = selections.value.map((el: InterWarehousePage) => el.id).join(',') const str = selections.value.map((el: InterWarehousePage) => el.id).join(',')
await deleteWarehouseOutRecordApi(str) await deleteStackingPlanApi(str)
ElMessage.success('删除成功') ElMessage.success('删除成功')
search() search()
await getTreeNum() await getTreeNum()
...@@ -1782,15 +1812,15 @@ const nodeClick = (data: InterWarehouseTree) => { ...@@ -1782,15 +1812,15 @@ const nodeClick = (data: InterWarehouseTree) => {
} }
const searchDetail = async () => { const searchDetail = async () => {
try { try {
const res = await getItemListByIdApi(currentRow.value?.id) const res = await getStackingPlanDetailApi(currentRow.value?.id)
detailList.value = res.data || [] detailList.value = res.data?.productList || []
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
} }
const getLogList = async () => { const getLogList = async () => {
try { try {
const res = await getOutRecordLogApi(currentRow.value?.id) const res = await getStackingPlanLogApi(currentRow.value?.id)
logList.value = res.data logList.value = res.data
} catch (e) { } catch (e) {
console.error(e) console.error(e)
...@@ -1800,6 +1830,10 @@ const locationList = ref<ILocation[]>([]) ...@@ -1800,6 +1830,10 @@ const locationList = ref<ILocation[]>([])
const locationLoading = ref(false) const locationLoading = ref(false)
const fetchLocationList = async (query: string) => { const fetchLocationList = async (query: string) => {
// if (!query) {
// locationList.value = []
// return
// }
if (!editForm.value.warehouseId) return if (!editForm.value.warehouseId) return
locationLoading.value = true locationLoading.value = true
try { try {
...@@ -1814,6 +1848,27 @@ const fetchLocationList = async (query: string) => { ...@@ -1814,6 +1848,27 @@ const fetchLocationList = async (query: string) => {
locationCode: item.locationCode, locationCode: item.locationCode,
} }
}) })
if (otherPurchaseData.value?.length > 0) {
//const importedSkus = otherPurchaseData.value.map((item) => item.warehouseSku).join(',')
// // 3. 调用 batchAddCommodity 获取商品的完整信息并过滤掉已有的 SKU
// const filteredSkusList = await batchAddCommodity(importedSkus)
// console.log('filteredSkusList', otherPurchaseData.value)
// 新增时切换仓库将重新匹配表格库位,确保该商品的库位和仓库一一对应
otherPurchaseData.value = otherPurchaseData.value.map(
(item: InterProductList) => {
const foundItem = locationList.value.find(
(locationItem: ILocation) =>
locationItem.locationCode === item.locationCode,
)
// 创建新对象而不是修改原对象
return {
...item,
locationCode: foundItem ? foundItem.locationCode : '',
locationId: foundItem ? foundItem.locationId : null,
}
},
)
}
} catch (e) { } catch (e) {
locationList.value = [] locationList.value = []
} finally { } finally {
...@@ -1863,20 +1918,24 @@ onMounted(() => { ...@@ -1863,20 +1918,24 @@ onMounted(() => {
width: 500px; width: 500px;
text-align: center; text-align: center;
} }
.cursor-pointer { .cursor-pointer {
cursor: pointer; cursor: pointer;
} }
.header-filter-form { .header-filter-form {
:deep(.el-form-item) { :deep(.el-form-item) {
margin-right: 14px; margin-right: 14px;
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
.product-dialog-footer { .product-dialog-footer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin: 8px 0; margin: 8px 0;
} }
$border: solid 1px #ddd; $border: solid 1px #ddd;
.send-order-list { .send-order-list {
...@@ -1924,10 +1983,12 @@ $border: solid 1px #ddd; ...@@ -1924,10 +1983,12 @@ $border: solid 1px #ddd;
.left { .left {
width: 160px; width: 160px;
:deep(.el-tree-node__content) { :deep(.el-tree-node__content) {
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
} }
:deep(.el-tree-node__label) { :deep(.el-tree-node__label) {
font-size: 13px; font-size: 13px;
cursor: pointer; cursor: pointer;
...@@ -2019,6 +2080,7 @@ $border: solid 1px #ddd; ...@@ -2019,6 +2080,7 @@ $border: solid 1px #ddd;
height: 5px; height: 5px;
background: #eff3f6; background: #eff3f6;
} }
.btn-list { .btn-list {
margin-bottom: 10px; margin-bottom: 10px;
} }
...@@ -2050,6 +2112,7 @@ $border: solid 1px #ddd; ...@@ -2050,6 +2112,7 @@ $border: solid 1px #ddd;
} }
} }
} }
.delivery-note-page { .delivery-note-page {
:deep(#top) { :deep(#top) {
height: 100%; height: 100%;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment