Commit 15e919c3 by wuqian

出库单

parent fb2d8f76
...@@ -438,6 +438,12 @@ export function getInRecordLogApi(inRecordId?: number) { ...@@ -438,6 +438,12 @@ export function getInRecordLogApi(inRecordId?: number) {
) )
} }
// 出库单 // 出库单
export function warehouseOutRecordExport(data: ExportInWarehouseInfo) {
return axios.post<never, BasePaginationData<never>>(
'factory/warehouseOutRecord/export',
data,
)
}
export function getOutRecordStatusTree() { export function getOutRecordStatusTree() {
return axios.get<never, BaseRespData<InterWarehouseTree[]>>( return axios.get<never, BaseRespData<InterWarehouseTree[]>>(
'factory/warehouseOutRecord/status_tree', 'factory/warehouseOutRecord/status_tree',
......
...@@ -14,6 +14,7 @@ export interface warehouseSearchForm { ...@@ -14,6 +14,7 @@ export interface warehouseSearchForm {
export interface InterProductList { export interface InterProductList {
createTime?: string createTime?: string
id?: number id?: number
inventoryId?: number | null
inId?: number inId?: number
productNo?: string | null //custom的货号 productNo?: string | null //custom的货号
buyStored?: number | null //入库数量 buyStored?: number | null //入库数量
...@@ -87,6 +88,9 @@ export interface InterProductList { ...@@ -87,6 +88,9 @@ export interface InterProductList {
warehouseSku?: string warehouseSku?: string
locationId?: number | null locationId?: number | null
locationCode?: string | null locationCode?: string | null
inventory?: {
usableInventory?: number
}
} }
export interface InterskuList { export interface InterskuList {
id?: number id?: number
......
...@@ -108,7 +108,6 @@ export function checkUpdateParams( ...@@ -108,7 +108,6 @@ export function checkUpdateParams(
removeList = arr1.map((item) => item['id'] as IdType) removeList = arr1.map((item) => item['id'] as IdType)
} }
if (isBackKeyName) { if (isBackKeyName) {
console.log(isBackKeyName)
// 将列表直接添加到 params 顶层 // 将列表直接添加到 params 顶层
if (addList.length > 0) params['addList'] = addList || undefined if (addList.length > 0) params['addList'] = addList || undefined
if (updateList.length > 0) if (updateList.length > 0)
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<template #top> <template #top>
<div class="header-filter-form"> <div class="header-filter-form">
<ElForm :model="searchForm" inline> <ElForm :model="searchForm" inline>
<ElFormItem label="采购仓库"> <ElFormItem label="仓库">
<ElSelect <ElSelect
v-model="searchForm.warehouseId" v-model="searchForm.warehouseId"
clearable clearable
...@@ -117,10 +117,10 @@ ...@@ -117,10 +117,10 @@
> >
删除 删除
</el-button> </el-button>
<!-- <el-button type="success" @click="handleExport"> 导出 </el-button> <el-button type="success" @click="handleExport"> 导出 </el-button>
<el-button type="primary" @click="printProductTag"> <el-button type="primary" @click="printProductTag">
打印商品SKU标签 打印商品SKU标签
</el-button> --> </el-button>
<el-button <el-button
v-if="nodeCode === 'PENDING_AUDIT'" v-if="nodeCode === 'PENDING_AUDIT'"
type="warning" type="warning"
...@@ -211,14 +211,6 @@ ...@@ -211,14 +211,6 @@
align="center" align="center"
></ElTableColumn> ></ElTableColumn>
<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
width="120" width="120"
...@@ -259,6 +251,7 @@ ...@@ -259,6 +251,7 @@
align="center" align="center"
></ElTableColumn> ></ElTableColumn>
<ElTableColumn <ElTableColumn
v-if="nodeCode === 'PENDING_SUBMIT'"
width="100" width="100"
align="center" align="center"
header-align="center" header-align="center"
...@@ -572,13 +565,13 @@ ...@@ -572,13 +565,13 @@
<div class="product-dialog-footer"> <div class="product-dialog-footer">
<div> <div>
<el-input <el-input
v-model="selectSku" v-model.trim="selectSku"
placeholder="商品SKU" placeholder="商品SKU"
style="width: 200px; margin: 0 10px" style="width: 200px; margin: 0 10px"
clearable clearable
size="small" size="small"
></el-input> ></el-input>
<el-popover placement="top-start" width="900" 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="skuData" height="100%" border>
<ElTableColumn <ElTableColumn
...@@ -658,14 +651,14 @@ ...@@ -658,14 +651,14 @@
</el-button> </el-button>
</template> </template>
</el-popover> </el-popover>
<!-- <el-button <el-button
style="margin-left: 6px" style="margin-left: 6px"
type="success" type="success"
size="small" size="small"
@click="addPurchase" @click="addPurchase"
> >
批量新增 批量新增
</el-button> --> </el-button>
<el-button <el-button
type="danger" type="danger"
style="margin-left: 10px" style="margin-left: 10px"
...@@ -754,7 +747,7 @@ ...@@ -754,7 +747,7 @@
<el-table-column align="center" prop="number" label="打印数量"> <el-table-column align="center" prop="number" label="打印数量">
<template #default="{ row }"> <template #default="{ row }">
<el-input <el-input
v-model="row.number" v-model.number="row.number"
oninput="value=value.replace(/[^\-?\d.]/g,'')" oninput="value=value.replace(/[^\-?\d.]/g,'')"
placeholder="打印数量" placeholder="打印数量"
clearable clearable
...@@ -767,6 +760,33 @@ ...@@ -767,6 +760,33 @@
<el-button type="primary" @click="handlePrintProductTag">打印</el-button> <el-button type="primary" @click="handlePrintProductTag">打印</el-button>
</template> </template>
</el-dialog> </el-dialog>
<ElDialog
v-model="addPurchaseVisible"
title="批量添加"
width="500px"
:close-on-click-modal="false"
>
<div>
<el-input
v-model.trim="purchaseTextarea"
type="textarea"
placeholder="请输入库存 SKU"
:rows="5"
minlength="1"
maxlength="1000"
show-word-limit
/>
<div style="margin-top: 12px; color: #777">
{{ '多个字段使用_##_,_##_隔开' }}
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="addPurchaseVisible = false">取消</el-button>
<el-button type="primary" @click="submitPurchase">确认</el-button>
</span>
</template>
</ElDialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
...@@ -793,9 +813,10 @@ import { ...@@ -793,9 +813,10 @@ import {
rejectOutRecordApi, rejectOutRecordApi,
LogListData, LogListData,
warehouseInfo, warehouseInfo,
warehouseOutRecordExport,
} from '@/api/warehouse' } from '@/api/warehouse'
// factoryWarehouseInventoryPrint, // factoryWarehouseInventoryPrint,
// import { filePath } from '@/api/axios.ts' 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'
...@@ -962,8 +983,8 @@ const { ...@@ -962,8 +983,8 @@ const {
{ {
...searchForm.value, ...searchForm.value,
billStatus: nodeCode.value == 'all' ? 'all' : nodeCode.value, billStatus: nodeCode.value == 'all' ? 'all' : nodeCode.value,
createTimeStart: tradingTime.value && tradingTime.value[0], startTime: tradingTime.value && tradingTime.value[0],
createTimeEnd: tradingTime.value && tradingTime.value[1], endTime: tradingTime.value && tradingTime.value[1],
}, },
page, page,
pageSize, pageSize,
...@@ -1025,42 +1046,120 @@ async function handlePrintProductTag() { ...@@ -1025,42 +1046,120 @@ 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[]> => {
if (!editForm.value.warehouseId) {
ElMessage.error('请选择仓库')
return []
}
try {
const res = await getBySkuAndWarehouseIdApi(editForm.value.warehouseId, sku)
const arr: InterskuList[] = res.data || []
const ids: Record<string, boolean> = {}
// 过滤掉商品列表已经加了的
for (const item of otherPurchaseData.value) {
if (item.warehouseSku !== undefined) {
ids[item.warehouseSku] = true
}
}
// 使用 filter 方法过滤掉已经存在的 SKU
const filteredArr = arr.filter((currentItem: InterskuList) => {
return (
currentItem.warehouseSku === undefined || !ids[currentItem.warehouseSku]
)
})
return filteredArr
} catch (e) {
console.error(e)
return []
}
}
interface InterImportData {
warehouseSku: string
remark?: string | null
[key: string]: unknown
}
// 前端导入Excel // 前端导入Excel
const excelFieldMap: Record<string, keyof InterProductList> = { const excelFieldMap: Record<string, keyof InterImportData> = {
SKU图片: 'skuImage', // SKU图片: 'skuImage',
商品SKU: 'warehouseSku', 商品SKU: 'warehouseSku',
SKU名称: 'skuName', // SKU名称: 'skuName',
出库数量: 'outCount', // 出库数量: 'outCount',
可用库存数量: 'usableInventory', // 可用库存数量: 'usableInventory',
'成本价(¥)': 'costPrice', // '成本价(¥)': 'costPrice',
'总成本(¥)': 'totalPrice', // '总成本(¥)': 'totalPrice',
库位: 'locationCode', // 库位: 'locationCode',
备注: 'remark', 备注: 'remark',
} }
const handleLocalImport = async ({
const handleLocalImport = ({
path, path,
data, data,
}: { }: {
path: string path: string
data: InterProductList[] data: InterImportData[]
}) => { }) => {
const result: InterProductList[] = data.map((item) => { // 1. 将原始导入数据映射到 InterImportData[]
const obj = {} as InterProductList const importedData: InterImportData[] = data
Object.keys(excelFieldMap).forEach((excelKey) => { .map((item) => {
const field = excelFieldMap[excelKey] as keyof InterProductList const obj: InterImportData = { warehouseSku: '' }
const value = item[excelKey] Object.keys(excelFieldMap).forEach((excelKey) => {
// // 类型转换和默认值 const field = excelFieldMap[excelKey]
// if (['outCount', 'costPrice', 'totalPrice'].includes(field)) { const value = item[excelKey]
// value = value == null || value === '' ? 0 : Number(value) // 根据目标字段进行可能的类型转换或处理
// } else { if (field === 'warehouseSku') {
// value = value == null ? '' : value obj[field] = typeof value === 'string' ? value : String(value ?? '') // 转换为字符串,处理 null/undefined
// } } else if (field === 'remark') {
obj[field] = value as InterProductList[typeof field] obj[field] =
typeof value === 'string'
? value
: value === null || value === undefined
? null
: String(value) // 备注可以是 string | null
} else {
// 处理其他字段
obj[field] = value
}
})
return obj
}) })
return obj .filter((item) => item.warehouseSku) // 过滤掉没有 SKU 的行
if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的商品SKU')
importDialogVisible.value = false
return
}
// 2. 提取导入的 SKU 列表
const importedSkus = importedData.map((item) => item.warehouseSku).join(',')
// 3. 调用 batchAddCommodity 获取商品的完整信息并过滤掉已有的 SKU
const filteredSkusList = await batchAddCommodity(importedSkus) // 使用 await 等待结果
if (filteredSkusList.length === 0) {
ElMessage.warning('导入的商品SKU已存在或无效')
importedFileUrl.value = path
importDialogVisible.value = false
return
}
// 4. 将备注信息合并到获取到的商品列表中
const mergedProductList = filteredSkusList.map((skuItem) => {
// 在导入数据中找到匹配的备注信息
const importedItem = importedData.find(
(item) => item.warehouseSku === skuItem.warehouseSku,
)
return {
skuImage: skuItem.image,
warehouseSku: skuItem.warehouseSku,
skuName: skuItem.skuName,
productNo: skuItem.productNumber,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.price,
outCount: null, // 出库数量初始为 null
totalPrice: null,
usableInventory: skuItem.usableInventory,
inventoryId: skuItem.id,
remark: importedItem?.remark ?? null,
} as InterProductList // 明确类型
}) })
otherPurchaseData.value = result // 5. 更新 otherPurchaseData
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
importedFileUrl.value = path importedFileUrl.value = path
importDialogVisible.value = false importDialogVisible.value = false
} }
...@@ -1069,10 +1168,42 @@ const exportForm = ref({ ...@@ -1069,10 +1168,42 @@ const exportForm = ref({
delivery: false, delivery: false,
resource: '', resource: '',
}) })
// const handleExport = () => { const handleExport = () => {
// exportVisible.value = true exportVisible.value = true
// } }
const submitExportForm = () => {} const submitExportForm = async () => {
if (exportForm.value.resource === '') {
return ElMessage.error('请选择导出类型')
}
let purchaseIds = []
let exportTotal: number | undefined = undefined
const params: AnyObject = {}
const resourceType = Number(exportForm.value.resource)
if (resourceType === 0) {
purchaseIds = tableData.value.map((el: InterWarehousePage) => el.id)
} else if (resourceType === 1) {
purchaseIds = selections.value.map((el: InterWarehousePage) => el.id)
} else if (resourceType === 2) {
purchaseIds = []
exportTotal = total.value
params.billStatus = nodeCode.value == 'all' ? 'all' : nodeCode.value
}
params.idList = purchaseIds
if (exportTotal !== undefined) {
params.total = exportTotal
}
try {
const res = await warehouseOutRecordExport({
showDetail: exportForm.value.delivery,
...params,
...searchForm.value,
})
window.open(filePath + res.message, '_blank')
exportVisible.value = false
} catch (e) {
exportVisible.value = false
}
}
const getWarehouseList = async () => { const getWarehouseList = async () => {
try { try {
const res = await warehouseInfoGetAll() const res = await warehouseInfoGetAll()
...@@ -1099,7 +1230,25 @@ const selectbySku = async () => { ...@@ -1099,7 +1230,25 @@ const selectbySku = async () => {
editForm.value.warehouseId, editForm.value.warehouseId,
selectSku.value, selectSku.value,
) )
skuData.value = res.data || [] 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)
} }
...@@ -1115,6 +1264,7 @@ const skudblclick = (val: InterskuList) => { ...@@ -1115,6 +1264,7 @@ const skudblclick = (val: InterskuList) => {
image = '', image = '',
locationId = null, locationId = null,
usableInventory = null, usableInventory = null,
id = null,
} = val || {} } = val || {}
otherPurchaseData.value = [ otherPurchaseData.value = [
...otherPurchaseData.value, ...otherPurchaseData.value,
...@@ -1129,6 +1279,7 @@ const skudblclick = (val: InterskuList) => { ...@@ -1129,6 +1279,7 @@ const skudblclick = (val: InterskuList) => {
outCount: null, //出库数量 outCount: null, //出库数量
totalPrice: null, totalPrice: null,
usableInventory, //可用库存数量 usableInventory, //可用库存数量
inventoryId: id,
}, },
] ]
// 使用filter代替forEach+splice,时间复杂度从O(n^2)降到O(n) // 使用filter代替forEach+splice,时间复杂度从O(n^2)降到O(n)
...@@ -1203,8 +1354,21 @@ const addDialog = async (i: number, v: InterWarehousePage | null) => { ...@@ -1203,8 +1354,21 @@ 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 getWarehouseOutRecordDetailApi(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 = res.data?.productList || [] otherPurchaseData.value = newProductList || []
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
...@@ -1415,7 +1579,7 @@ const upSection = async () => { ...@@ -1415,7 +1579,7 @@ const upSection = async () => {
editForm.value as unknown as AnyObject, editForm.value as unknown as AnyObject,
'id', 'id',
{ {
productList: 'warehouseSku', productList: 'id',
}, },
) )
try { try {
...@@ -1428,9 +1592,36 @@ const upSection = async () => { ...@@ -1428,9 +1592,36 @@ const upSection = async () => {
console.error(e) console.error(e)
} }
} }
// const addPurchase = async () => { const addPurchaseVisible = ref(false)
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库') const purchaseTextarea = ref(null)
// } const addPurchase = async () => {
addPurchaseVisible.value = true
}
const submitPurchase = async () => {
if (!purchaseTextarea.value) {
ElMessage.warning('请输入库存 SKU')
return
}
const filteredSkusList = await batchAddCommodity(purchaseTextarea.value)
const mergedProductList = filteredSkusList.map((skuItem) => {
return {
skuImage: skuItem.image,
warehouseSku: skuItem.warehouseSku,
skuName: skuItem.skuName,
productNo: skuItem.productNumber,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.price,
outCount: null,
totalPrice: null,
usableInventory: skuItem.usableInventory,
inventoryId: skuItem.id,
remark: null,
} as InterProductList
})
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
addPurchaseVisible.value = false
}
const deleteOtherWarehousing = () => { const deleteOtherWarehousing = () => {
const arr = otherWarehouseSelection.value const arr = otherWarehouseSelection.value
if (arr.length === 0) return if (arr.length === 0) return
...@@ -1442,8 +1633,8 @@ const deleteOtherWarehousing = () => { ...@@ -1442,8 +1633,8 @@ const deleteOtherWarehousing = () => {
const importDialogVisible = ref(false) const importDialogVisible = ref(false)
const importedFileUrl = ref('') const importedFileUrl = ref('')
const importData = async () => { const importData = async () => {
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库')
importDialogVisible.value = true importDialogVisible.value = true
importedFileUrl.value = ''
} }
const handleBatchDelete = async () => { const handleBatchDelete = async () => {
if (!selections.value.length) { if (!selections.value.length) {
...@@ -1465,11 +1656,6 @@ const nodeClick = (data: InterWarehouseTree) => { ...@@ -1465,11 +1656,6 @@ const nodeClick = (data: InterWarehouseTree) => {
sessionStorage.setItem('InRecord_NodeCode', data.code ?? '') sessionStorage.setItem('InRecord_NodeCode', data.code ?? '')
search() search()
} }
// const detailPager = ref({
// page: 1,
// rows: 100,
// total: 0,
// })
const searchDetail = async () => { const searchDetail = async () => {
try { try {
const res = await getItemListByIdApi(currentRow.value?.id) const res = await getItemListByIdApi(currentRow.value?.id)
...@@ -1490,10 +1676,6 @@ const locationList = ref<ILocation[]>([]) ...@@ -1490,10 +1676,6 @@ 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 {
......
...@@ -446,12 +446,6 @@ ...@@ -446,12 +446,6 @@
/> />
</div> </div>
</div> </div>
<!-- <template #footer>
<span class="dialog-footer">
<el-button @click="importDialogVisible = false">取消</el-button>
<el-button type="primary" @click="packedData">确认</el-button>
</span>
</template> -->
</ElDialog> </ElDialog>
<ElDialog <ElDialog
v-model="newDialogVisible" v-model="newDialogVisible"
...@@ -607,7 +601,7 @@ ...@@ -607,7 +601,7 @@
<div class="product-dialog-footer"> <div class="product-dialog-footer">
<div> <div>
<el-input <el-input
v-model="selectSku" v-model.trim="selectSku"
placeholder="商品SKU" placeholder="商品SKU"
style="width: 200px; margin: 0 10px" style="width: 200px; margin: 0 10px"
clearable clearable
...@@ -693,14 +687,14 @@ ...@@ -693,14 +687,14 @@
</el-button> </el-button>
</template> </template>
</el-popover> </el-popover>
<!-- <el-button <el-button
style="margin-left: 6px" style="margin-left: 6px"
type="success" type="success"
size="small" size="small"
@click="addPurchase" @click="addPurchase"
> >
批量新增 批量新增
</el-button> --> </el-button>
<el-button <el-button
type="danger" type="danger"
style="margin-left: 10px" style="margin-left: 10px"
...@@ -789,7 +783,7 @@ ...@@ -789,7 +783,7 @@
<el-table-column align="center" prop="number" label="打印数量"> <el-table-column align="center" prop="number" label="打印数量">
<template #default="{ row }"> <template #default="{ row }">
<el-input <el-input
v-model="row.number" v-model.number="row.number"
oninput="value=value.replace(/[^\-?\d.]/g,'')" oninput="value=value.replace(/[^\-?\d.]/g,'')"
placeholder="打印数量" placeholder="打印数量"
clearable clearable
...@@ -802,6 +796,33 @@ ...@@ -802,6 +796,33 @@
<el-button type="primary" @click="handlePrintProductTag">打印</el-button> <el-button type="primary" @click="handlePrintProductTag">打印</el-button>
</template> </template>
</el-dialog> </el-dialog>
<ElDialog
v-model="addPurchaseVisible"
title="批量添加"
width="500px"
:close-on-click-modal="false"
>
<div>
<el-input
v-model.trim="purchaseTextarea"
type="textarea"
placeholder="请输入库存 SKU"
:rows="5"
minlength="1"
maxlength="1000"
show-word-limit
/>
<div style="margin-top: 12px; color: #777">
{{ '多个字段使用_##_,_##_隔开' }}
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="addPurchaseVisible = false">取消</el-button>
<el-button type="primary" @click="submitPurchase">确认</el-button>
</span>
</template>
</ElDialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
...@@ -1078,41 +1099,107 @@ async function handlePrintProductTag() { ...@@ -1078,41 +1099,107 @@ 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[]> => {
if (!editForm.value.warehouseId) {
ElMessage.error('请选择仓库')
return []
}
try {
const res = await getBySkuApi(editForm.value.warehouseId, sku)
const arr: InterskuList[] = res.data || []
const ids: Record<string, boolean> = {}
// 过滤掉商品列表已经加了的
for (const item of otherPurchaseData.value) {
if (item.warehouseSku !== undefined) {
ids[item.warehouseSku] = true
}
}
// 使用 filter 方法过滤掉已经存在的 SKU
const filteredArr = arr.filter((currentItem: InterskuList) => {
return currentItem.sku === undefined || !ids[currentItem.sku]
})
return filteredArr
} catch (e) {
console.error(e)
return []
}
}
interface InterImportData {
warehouseSku: string
remark?: string | null
[key: string]: unknown
}
// 前端导入Excel // 前端导入Excel
const excelFieldMap: Record<string, keyof InterProductList> = { const excelFieldMap: Record<string, keyof InterProductList> = {
SKU图片: 'skuImage', // SKU图片: 'skuImage',
商品SKU: 'warehouseSku', 商品SKU: 'warehouseSku',
SKU名称: 'skuName', // SKU名称: 'skuName',
入库数量: 'buyStored', 入库数量: 'buyStored',
'成本价(¥)': 'costPrice', // '成本价(¥)': 'costPrice',
'总成本(¥)': 'totalPrice', // '总成本(¥)': 'totalPrice',
库位: 'locationCode', // 库位: 'locationCode',
备注: 'remark', 备注: 'remark',
} }
const handleLocalImport = ({ const handleLocalImport = async ({
path, path,
data, data,
}: { }: {
path: string path: string
data: InterProductList[] data: InterImportData[]
}) => { }) => {
const result: InterProductList[] = data.map((item) => { // 1. 将原始导入数据映射到 InterImportData[]
const obj = {} as InterProductList const importedData: InterImportData[] = data
Object.keys(excelFieldMap).forEach((excelKey) => { .map((item) => {
const field = excelFieldMap[excelKey] as keyof InterProductList const obj: InterImportData = { warehouseSku: '' }
const value = item[excelKey] Object.keys(excelFieldMap).forEach((excelKey) => {
// // 类型转换和默认值 const field = excelFieldMap[excelKey]
// if (['buyStored', 'costPrice', 'totalPrice'].includes(field)) { const value = item[excelKey]
// value = value == null || value === '' ? 0 : Number(value) obj[field] = value
// } else { })
// value = value == null ? '' : value return obj
// }
obj[field] = value as InterProductList[typeof field]
}) })
return obj .filter((item) => item.warehouseSku) // 过滤掉没有 SKU 的行
if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的商品SKU')
importDialogVisible.value = false
return
}
// 2. 提取导入的 SKU 列表
const importedSkus = importedData.map((item) => item.warehouseSku).join(',')
// 3. 调用 batchAddCommodity 获取商品的完整信息并过滤掉已有的 SKU
const filteredSkusList = await batchAddCommodity(importedSkus) // 使用 await 等待结果
if (filteredSkusList.length === 0) {
ElMessage.warning('导入的商品SKU已存在或无效')
importedFileUrl.value = path
importDialogVisible.value = false
return
}
// 4. 将备注信息合并到获取到的商品列表中
const mergedProductList = filteredSkusList.map((skuItem) => {
// 在导入数据中找到匹配的备注信息
const importedItem = importedData.find(
(item) => item.warehouseSku === skuItem.sku,
)
const amount = new BigNumber(importedItem?.buyStored)
.multipliedBy(skuItem.factoryPrice)
.toFixed(2)
return {
skuImage: skuItem.image,
warehouseSku: skuItem.sku,
skuName: skuItem.skuName,
productNo: skuItem.productNo,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.factoryPrice,
buyStored: importedItem?.buyStored ?? null,
totalPrice: Number(amount),
usableInventory: skuItem.usableInventory,
remark: importedItem?.remark ?? null,
} as InterProductList // 明确类型
}) })
otherPurchaseData.value = result // 5. 更新 otherPurchaseData
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
importedFileUrl.value = path importedFileUrl.value = path
importDialogVisible.value = false importDialogVisible.value = false
} }
...@@ -1416,31 +1503,6 @@ const addOtherCurrency = async () => { ...@@ -1416,31 +1503,6 @@ const addOtherCurrency = async () => {
return return
} }
} }
// 看新增后要不要打印标签
// 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 {
...@@ -1508,9 +1570,35 @@ const upSection = async () => { ...@@ -1508,9 +1570,35 @@ const upSection = async () => {
console.error(e) console.error(e)
} }
} }
// const addPurchase = async () => { const addPurchaseVisible = ref(false)
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库') const purchaseTextarea = ref(null)
// } const addPurchase = async () => {
addPurchaseVisible.value = true
}
const submitPurchase = async () => {
if (!purchaseTextarea.value) {
ElMessage.warning('请输入库存 SKU')
return
}
const filteredSkusList = await batchAddCommodity(purchaseTextarea.value)
const mergedProductList = filteredSkusList.map((skuItem) => {
return {
skuImage: skuItem.image,
warehouseSku: skuItem.sku,
skuName: skuItem.skuName,
productNo: skuItem.productNo,
locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null,
costPrice: skuItem.factoryPrice,
buyStored: null,
totalPrice: null,
usableInventory: skuItem.usableInventory,
remark: null,
} as InterProductList
})
otherPurchaseData.value = [...otherPurchaseData.value, ...mergedProductList]
addPurchaseVisible.value = false
}
const deleteOtherWarehousing = () => { const deleteOtherWarehousing = () => {
const arr = otherWarehouseSelection.value const arr = otherWarehouseSelection.value
if (arr.length === 0) return if (arr.length === 0) return
...@@ -1522,8 +1610,8 @@ const deleteOtherWarehousing = () => { ...@@ -1522,8 +1610,8 @@ const deleteOtherWarehousing = () => {
const importDialogVisible = ref(false) const importDialogVisible = ref(false)
const importedFileUrl = ref('') const importedFileUrl = ref('')
const importData = async () => { const importData = async () => {
// if (!editForm.value.warehouseId) return ElMessage.error('请选择仓库')
importDialogVisible.value = true importDialogVisible.value = true
importedFileUrl.value=''
} }
const handleBatchDelete = async () => { const handleBatchDelete = async () => {
if (!selections.value.length) { if (!selections.value.length) {
......
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